Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型版本中类型转换泛型对象_C#_.net_Generics - Fatal编程技术网

C# 在泛型版本中类型转换泛型对象

C# 在泛型版本中类型转换泛型对象,c#,.net,generics,C#,.net,Generics,我有一个界面,其中说明: public interface IMyType<T> where T: IMySubType { event EventHandler<IMyType<T>, EventArgs<T>> OnSomething; IEnumerable<T> AvailableThings{get;} void Start(); } 公共接口IMyType,其中T:IMySubType{ 事件处理程

我有一个界面,其中说明:

public interface IMyType<T> where T: IMySubType {
    event EventHandler<IMyType<T>, EventArgs<T>> OnSomething;
    IEnumerable<T> AvailableThings{get;}
    void Start();
}
公共接口IMyType,其中T:IMySubType{
事件处理程序;
IEnumerable AvailableThings{get;}
void Start();
}
我有一个
列表
,如何将
IMyType
添加到此列表中?(
IMySubType
IMySubType
界面执行

我试图将我的
T
泛型类型作为协变类型,但它似乎不适用于使用此类型作为事件的接口(不知道为什么)

那么,如何在列表的每个元素上存储、迭代和调用start方法呢

因为目前我的另一个选择是创建一个没有通用性的新接口,并进行双重实现(因为在大多数情况下,我需要具有这种通用性。

这个如何:

public interface IMyType { }

public interface IMyType<T> : IMyType where T : IMySubType
{
    event EventHandler<IMyType<T>, EventArgs<T>> OnSomething;
    IEnumerable<T> AvailableThings{get;}
    void Start();
}
如何将
IMyType
添加到此列表中

IMyType
需要协变才能工作。协变意味着泛型类型只能包含在函数的输出中。由于您的接口包含一个将泛型类型作为输入一部分的
EventHandler
,因此您的接口不能协变

让我们更改接口名称以了解原因。假设您运行一个zoo并希望区分“仅查看”笼子和“正常”笼子。因此您有两个接口:

IViewOnlyCage<out T>
{
    public T View();
}

ICage<T>
{
    public Add(T animal);
}
由于您的接口包含间接输入,因此可能会出现如下情况:

List<IMyType<IMySubType>> list = new List<IMyType<IMySubType>>();

list.Add(new IMyType<SubTypeImplementation>());

IMyType<IMySubType> item = list[0];  // seems OK

item.OnSomething += new EventHandler(IMyType<SecondSubType>, EventArgs<SecondSubType>);   
List List=新列表();
添加(新的IMyType());
IMyType item=list[0];//似乎正常
item.OnSomething+=新的EventHandler(IMyType,EventArgs);
但是实际的泛型类型是
子类型实现
,而不是
第二个子类型
,因此存在类型冲突


最简单的更改似乎是将事件处理程序移动到另一个界面。然后,您可以使
IMyType
协变,并创建一个
列表

什么不起作用?您是否尝试过添加对象?是否出现编译错误?
系统。EventArgs
不是通用类型。为什么将其用作generic?系统也是如此。EventHandler@o_weisman:运行时错误,说我不能输入这个+Resharper警告我。@DmytroShevchenko抱歉,
EventArgs
是我们自己的对象,它来自
EventArgs
嗯,我不知道我收到的是哪种泛型编辑bis:就像我说的,这个类的主要用途是对不同类型的子项有相同的行为。但在我的新案例中,我需要能够匿名获取它们,我想知道是否有办法做到这一点it@J4N多态性在泛型上不起作用。例如,
IEnumerable
,它的类型与(它也不是从中继承的)不同
IEnumerable
。这是我看到的解决问题的唯一方法。@J4N列表不支持协变。是否有其他IEnumerable类型支持它?好的。是否有一种解决方法可以使事件包含泛型类型?@J4N不会使
IMyType
协变。您将不得不接受更多规范的列表fic类型。这并不能解决我的问题。不幸的是,在很多情况下,我需要得到具体的版本。此外,我理解装箱问题,但在我的情况下,我不明白我怎么会有这样的问题,因为我总是使用这种类型作为“输出”,我唯一可以使用它的方法是“更通用”。我不返回任何内容的列表,我使用列表存储类的通用版本,但可设置事件处理程序允许输入“派生”类型,这是不允许的。我将添加一些选项,但没有魔弹。
public interface IMyType
{
     event EventHandler<IMySubType, EventArgs<IMySubType>> OnSomething;
     IEnumerable<IMySubType> AvailableThings { get; }
     void Start();
}
IViewOnlyCage<out T>
{
    public T View();
}

ICage<T>
{
    public Add(T animal);
}
List<IViewOnlyCage<IAnimal>> list1;
List<ICage<IAnimal>> list2;
list1.Add(new Cage<Tiger>());
list1.Add(new Cage<Deer>());
list2.Add(new Cage<Tiger>());

ICage<IAnimal> cage = list2[0];  // a reference to the tiger cage
cage.Add(new Deer());  //uh-oh... bad news for the deer
List<IMyType<IMySubType>> list = new List<IMyType<IMySubType>>();

list.Add(new IMyType<SubTypeImplementation>());

IMyType<IMySubType> item = list[0];  // seems OK

item.OnSomething += new EventHandler(IMyType<SecondSubType>, EventArgs<SecondSubType>);