contravariance

Why wasn't TEventArgs made contravariant in the standard event pattern in the .NET ecosystem?

断了今生、忘了曾经 提交于 2019-12-03 14:53:07
问题 When learning more about the standard event model in .NET, I found that before introducing generics in C#, the method that will handle an event is represented by this delegate type: // // Summary: // Represents the method that will handle an event that has no event data. // // Parameters: // sender: // The source of the event. // // e: // An object that contains no event data. public delegate void EventHandler(object sender, EventArgs e); But after generics were introduced in C# 2, I think

Covariance and Contravariance - Just different mechanisms for invoking guaranteed base class behavior?

陌路散爱 提交于 2019-12-03 13:52:01
I'm having a struggle understanding these two concepts. But I think after many videos and SO QA's, I have it distilled down to its simplest form: Covariant - Assumes a sub-type can do what its base-type does. Contravariant - Assumes you can treat a sub-type the same way you would treat its base-type. Supposing these three classes: class Animal { void Live(Animal animal) { //born! } void Die(Animal animal) { //dead! } } class Cat : Animal { } class Dog : Animal { } Covariant Any animal can do what animals do. Assumes a sub-type can do what its base-type does. Animal anAnimal = new Cat();

How to determine type parameter's variance?

纵然是瞬间 提交于 2019-12-03 11:36:27
Inspired by Real-world examples of co- and contravariance in Scala I thought a better question would be: When designing a library, are there a specific set of questions you should ask yourself when determining whether a type parameter should be covariant or contravariant? Or should you make everything invariant and then change as needed? Well, simple, does it make sense? Think of Liskov substitution. Co-variance If A <: B , does it make sense to pass a C[A] where a C[B] is expected? If so, make it C[+T] . The classic example is the immutable List , where a List[A] can be passed to anything

Covariance vs. contravariance with respect to class inheritance

风流意气都作罢 提交于 2019-12-03 08:05:57
What is the meaning of the concepts 'covariance' and 'contravariance'? Given 2 classes, Animal and Elephant (which inherits from Animal ), my understanding is that you would get a run-time errors if you try and put an Elephant into an array of Animals, and this happens because Elephant is "bigger" (more specific) than Animal. But could you place an Animal into an array of Elephant, seeing how Elephant is guaranteed to contain the Animal properties? You have it backwards. You can add an Elephant to an Animal array because it is an Animal, and it's guaranteed to have all of the methods an Animal

Contravariance vs Covariance in Scala

跟風遠走 提交于 2019-12-03 06:10:12
问题 I just learned Scala. Now I am confused about Contravariance and Covariance. From this page, I learned something below: Covariance Perhaps the most obvious feature of subtyping is the ability to replace a value of a wider type with a value of a narrower type in an expression. For example, suppose I have some types Real , Integer <: Real , and some unrelated type Boolean . I can define a function is_positive :: Real -> Boolean which operates on Real values, but I can also apply this function

Why wasn't TEventArgs made contravariant in the standard event pattern in the .NET ecosystem?

别等时光非礼了梦想. 提交于 2019-12-03 04:36:16
When learning more about the standard event model in .NET, I found that before introducing generics in C#, the method that will handle an event is represented by this delegate type: // // Summary: // Represents the method that will handle an event that has no event data. // // Parameters: // sender: // The source of the event. // // e: // An object that contains no event data. public delegate void EventHandler(object sender, EventArgs e); But after generics were introduced in C# 2, I think this delegate type was rewritten using genericity: // // Summary: // Represents the method that will

Problem understanding covariance contravariance with generics in C#

て烟熏妆下的殇ゞ 提交于 2019-12-03 02:06:44
问题 I can't understand why the following C# code doesn't compile. As you can see, I have a static generic method Something with an IEnumerable<T> parameter (and T is constrained to be an IA interface), and this parameter can't be implicitly converted to IEnumerable<IA> . What is the explanation? (I don't search for a workaround, just to understand why it doesn't work). public interface IA { } public interface IB : IA { } public class CIA : IA { } public class CIAD : CIA { } public class CIB : IB

No warning or error (or runtime failure) when contravariance leads to ambiguity

落花浮王杯 提交于 2019-12-03 01:38:05
问题 First, remember that a .NET String is both IConvertible and ICloneable . Now, consider the following quite simple code: //contravariance "in" interface ICanEat<in T> where T : class { void Eat(T food); } class HungryWolf : ICanEat<ICloneable>, ICanEat<IConvertible> { public void Eat(IConvertible convertibleFood) { Console.WriteLine("This wolf ate your CONVERTIBLE object!"); } public void Eat(ICloneable cloneableFood) { Console.WriteLine("This wolf ate your CLONEABLE object!"); } } Then try

No warning or error (or runtime failure) when contravariance leads to ambiguity

落爺英雄遲暮 提交于 2019-12-02 16:53:11
First, remember that a .NET String is both IConvertible and ICloneable . Now, consider the following quite simple code: //contravariance "in" interface ICanEat<in T> where T : class { void Eat(T food); } class HungryWolf : ICanEat<ICloneable>, ICanEat<IConvertible> { public void Eat(IConvertible convertibleFood) { Console.WriteLine("This wolf ate your CONVERTIBLE object!"); } public void Eat(ICloneable cloneableFood) { Console.WriteLine("This wolf ate your CLONEABLE object!"); } } Then try the following (inside some method): ICanEat<string> wolf = new HungryWolf(); wolf.Eat("sheep"); When one

Problem understanding covariance contravariance with generics in C#

谁都会走 提交于 2019-12-02 15:41:07
I can't understand why the following C# code doesn't compile. As you can see, I have a static generic method Something with an IEnumerable<T> parameter (and T is constrained to be an IA interface), and this parameter can't be implicitly converted to IEnumerable<IA> . What is the explanation? (I don't search for a workaround, just to understand why it doesn't work). public interface IA { } public interface IB : IA { } public class CIA : IA { } public class CIAD : CIA { } public class CIB : IB { } public class CIBD : CIB { } public static class Test { public static IList<T> Something<T>