Question 1: Why does s1.Transform (v) allow ITransform<ISelection> and not ITransform<IValue> , as in the second case?
For me, this is allowed by Selector.Transform<ISelection> . In addition, it should: you said that it is a selector, and the Selector has an open method called Transform, and it accepts ISelection. IValue extends ISelection. When will he be forced to ITransform? I do not believe that this illustrates any contravariance; I think it is an implicit transformation.
Question 2: For Question 1, it does not seem to matter if ITransform in or an invariant
since you use the generic parameter as the arg method, and not the return type, the rules determine that the parameter must be contravariantly valid, which would allow in and disable out .
public class Example { public interface ITransform<D> // or <in D> --> seems to make no difference here { void Transform(D data); //contravariant in ITranform<out D>. //D Transform(string input); //covariance ok } public interface ISelection { } public interface IValue : ISelection { } public interface IEditor : ITransform<IValue> { } public interface ISelector : IEditor, ITransform<ISelection> { new void Transform(ISelection data); } class Value : IValue { } class Editor : IEditor { public void Transform(IValue data) { throw new NotImplementedException(); } } class Foo : Editor, ISelector { public void Transform(ISelection data) { throw new NotImplementedException(); } } public void Whatever() { Value v = new Value(); Foo s1 = new Foo(); IEditor s2 = s1; s1.Transform(v); // resolves to Foo.Tranform(ISelection) s2.Transform(v); // resolves to ITransform<IValue> --> cast into IEditor, which sig says ITransform<IValue> } }
sweaver2112
source share