Tag: covariance

使用通用接口约束时的协方差/逆差异难题

public interface IShape{} public class Rectangle : IShape{} public class Base{} public class Derived : Base{} public interface IFoo where T : IShape where U : Base { T Convert(U myType); } public class MyFoo : IFoo { public Rectangle Convert(Derived myType) { throw new NotImplementedException(); } } class Program { static void Main(string[] args) […]

不同FW的协方差导致代码中断?

我在NDC 2010上看到了Jon Skeet的演讲 他提到了一些有趣的事 public Class Base { public void Foo(IEnumerable strings){} } public Class Child:Base { publc void Foo(IEnumerable objects) {} } Main : List lst = new List(); lst.Add(“aaa”); Child c = new Child(); c.Foo(lst); 使用C#3,它将调用: Base.Foo 使用C#4,它将调用: Child.Foo 我知道这是因为协方差 题 : 是不是有点代码破坏变化? 有没有解决方法,所以这段代码将继续像第3版那样工作?

IList在c#中使用协方差和逆变,这可能吗?

这有可能吗? (我没有对阵2010年,所以我不能自己尝试,对不起) public interface IComplexList where TOutput : TInput { public IEnumerator GetEnumerator(); public void Add(TInput item); } public interface IList : IComplexList { } 如果我做对了,你可以用它来在同一个界面中实际实现协方差和逆变。

在基类集合上调用派生方法

我有一个名为A的抽象类,以及实现A的其他类(B,C,D,E,…)。我的派生类包含不同类型的值。 我还有一个A对象列表。 abstract class A { } class B : class A { public int val {get;private set;} } class C : class A { public double val {get;private set;} } class D : class A { public string val {get;private set;} } class Program { static void Main(string[] args) { List list = new […]

转换generics和generics类型

考虑一下,我有以下3个类/接口: class MyClass { } interface IMyInterface { } class Derived : IMyInterface { } 我希望能够将MyClass转换为MyClass ,反之亦然: MyClass a = new MyClass(); MyClass b = (MyClass)a; 但是如果我尝试,我会遇到编译错误: Cannot convert type ‘MyClass’ to ‘MyClass’ 我确信有一个很好的理由我不能这样做,但我想不出一个。 至于我为什么要这样做 – 我想象的场景是你理想地希望使用MyClass的实例来避免许多讨厌的演员,但是你需要将你的实例传递给一个接口接受MyClass 。 所以我的问题是双重的: 为什么我不能在这两种类型之间施放? 有没有办法保持使用MyClass实例的MyClass同时仍然可以将其转换为MyClass ?

为什么这个协方差声明会编译?

考虑这个界面: interface Test where T : struct { } 它编译时没有错误或警告。 如本问题所述 ,并在协方差和反演法常见问题中提到: 仅当类型参数是引用类型时才支持差异。 那么为什么上面的接口编译? 对“out”关键字失败(或至少警告)是有意义的。 我想这个问题归结为 – 在上面的例子中使用out关键字是否有任何区别? 更新 :这是一个误导性行为的示例,可能会让那些看不到上面界面的不知情的开发人员漏掉: typeof(IDummy).IsAssignableFrom(typeof(MyStruct)); // should return true typeof(ITest).IsAssignableFrom(typeof(ITest)); // returns false 如果编码器不知道方差不适用于值类型,他们会期望第二行返回true – 因为out关键字 – 但它永远不会。 这正是导致我提出这个问题的错误…… 另一个可编译但产生意外结果的代码示例 : ITest foo = …; var casted = (ITest)foo; 我希望这可以工作(不知道协方差对引用类型的限制),但它会导致System.InvalidCastException。

协方差胜过具体类型?

说实话 – 我问过(这个问题的一部分) ,但现在我有一个不同的相关问题。 public class Base { public void Foo(IEnumerable strings) { } } public class Child : Base { public void Foo(IEnumerable objects) { } } List lst = new List(); lst.Add(“aaa”); Child c = new Child(); c.Foo(lst); (在C#3中它将调用:C#4中的Child.Foo将调用: Child.Foo ) 我在FW4! , 让我们来谈谈它 所有对协方差的尊重:当我写c.Foo(lst); (我是STRING的IEnumerable !) – 它看到两个签名! 但仍然 – 它选择IEnumerable ?? […]

分配IEnumerable(协方差)

由于IEnumerable在C#4.0中有一个协变参数,我很困惑它在以下代码中的行为方式。 public class Test { IEnumerable foos; public void DoTestOne(IEnumerable bars) where H : IFoo { foos = bars; } public void DoTestTwo(IEnumerable bars) { foos = bars; } } public interface IFoo { } public interface IBar : IFoo { } 所以基本上DoTestOne方法不会在DoTestTwo编译。 除了为什么它不起作用,如果有人知道我如何能够实现DoTestOne的效果(指定一个IEnumberable where H : IFoo到IEnumberable ),我将不胜感激。

逆变? 协方差? 这个通用架构有什么问题……?

我在设置命令处理架构时遇到了一些问题。 我希望能够创建从ICommand派生的许多不同的命令; 然后,创建从ICommandHandler派生的许多不同的命令处理程序; 这是我开始定义的接口和类: interface ICommand {} class CreateItemCommand : ICommand {} interface ICommandHandler where TCommand : ICommand { void Handle(TCommand command); } class CreateItemCommandHandler : ICommandHandler { public void Handle(CreateItemCommand command) { // Handle the command here } } 我有一个可以创建适当类型的命令的帮助程序类: class CommandResolver { ICommand GetCommand(Message message) { return new CreateItemCommand(); // Handle other commands […]

C#:私有内部接口可能吗?

我有一个通用类X ; 这个类有一个协变部分,我希望能够协同访问。 所以我把它分解成一个接口IX 。 但是,我希望这个接口只对类本身可见,因为它还包含private 。 即,在课堂内部,我可以向上升到IX并且共同使用它。 例如: class X : IX { private interface IX{ // the private covariant interface void foo(); } // It grants access to the private method `foo` private T foo(){…} public T IX.foo(){ return foo(); } private static void someMethod(IX x) { // Here I can use `x` […]