.NET interfaces that allow implicit snooping on non-derived types

I read the source code of Roslyn when I noticed this strange section:

// Implicit casts are not emitted. As a result verifier may operate on a different // types from the types of operands when performing stack merges in coalesce/ternary. // Such differences are in general irrelevant since merging rules work the same way // for base and derived types. // // Situation becomes more complicated with delegates, arrays and interfaces since they // allow implicit casts from types that do not derive from them. In such cases // we may need to introduce static casts in the code to prod the verifier to the // right direction 

I wonder what is needed for this. In particular, I care about when an interface allows implicit listing from a non-derived type. However, an explanation for arrays / delegates would be interesting as well.

+8
c # interface
source share
1 answer

Seems like a classic Covariance example in Generics: you can use an interface with a more general class, rather than a derivative.

So they

"allow implicit drops from types that are not derived from them"

since here you have an implicit translation from an interface with a base type to an interface with a derived type, therefore, from types (interfaces with basic types) that do not derive from them (interfaces with derived types).

In my example, you can see a covariant interface that calculates a region of a more derivative form, since it has a less derivative form, so you have a listing where, for example, the dimension is lost ...

 public class Basic { public double dim1; } public class Derived : Basic { public double dim2; } public interface IFactory<in T> { double Area(T shape); } class BasicFactory : IFactory<Basic> { public double Area(Basic shape) { return shape.dim1 * shape.dim1; } } class DerivedFactory : IFactory<Derived> { public double Area(Derived shape) { return shape.dim1 * shape.dim2; } } class Program { double Area(IFactory<Derived> factory, Derived shape) { return factory.Area(shape); } static void Main(string[] args) { IFactory<Basic> notDerived = new BasicFactory(); // from not derived type Derived shape = new Derived() { dim1 = 10, dim2 = 20 }; double area = new Program().Area(notDerived,shape); // cast! dimension loss Console.WriteLine(area); // 100 = 10*10 IFactory<Derived> derived = new DerivedFactory(); //from derived type area = new Program().Area(derived, shape); // no cast, now Console.WriteLine(area); // 200 = 10*20 Console.ReadKey(); } } 
+2
source share

All Articles