我有一个界面说明:
public interface IMyType<T> where T: IMySubType {
event EventHandler<IMyType<T>, EventArgs<T>> OnSomething;
IEnumerable<T> AvailableThings{get;}
void Start();
}
我是List<IMyType<IMySubType>>
,如何在此列表中添加IMyType<SubTypeImplementation>
? (SubTypeImplementation
界面中的IMySubType
herits。
我尝试将我的T
泛型类型作为协变,但它似乎不能使用此类型作为事件的接口(不确定知道原因)。
那么,我如何在列表的每个元素上存储,迭代和调用start方法?
因为目前我的另一个选择是创建一个没有通用性的新接口,并进行双重实现(因为在大多数情况下我需要具有这种通用性。
答案 0 :(得分:0)
这个怎么样:
<table class="table-c">
<tr>
<td style="width: 10%">REFERENCE NO.</td>
<td style="width: 30%">DESCRIPTION</td>
<td style="width: 10%">Invoice DATE</td>
<td style="width: 10%">INVOICE AMOUNT</td>
<td style="width: 20%">DISCOUNT TAKEN</td>
<td style="width: 20%">AMOUNT PAID</td>
</tr>
<tr style="height: 200px">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
<table class="table-c">
<tr>
<td style="width: 20%">CHECK DATA</td>
<td style="width: 10%">CHECK NO.</td>
<td style="width: 40%">PAYEE</td>
<td style="width: 10%">DISCOUNT TAKEN</td>
<td style="width: 20%">CHECK AMOUNT</td>
</tr>
<tr style="height: 200px">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
您的列表类型为public interface IMyType { }
public interface IMyType<T> : IMyType where T : IMySubType
{
event EventHandler<IMyType<T>, EventArgs<T>> OnSomething;
IEnumerable<T> AvailableThings{get;}
void Start();
}
:
List<IMyType>
当然,缺点是您需要在列表中强制转换每个元素才能使用它:
List<IMyType> myList = new List<IMyType>();
myList.Add(implementation1); // implementation1 is of type IMyType<SubTypeImplementation>
myList.Add(implementation2); // implementation2 is of type IMyType<SubTypeImplementation2>
无论如何,在这种情况下我不会使用泛型。
我的var impl = (IMyType<SubTypeImplementation>)list[0];
impl.Start();
看起来像这样:
IMyType
答案 1 :(得分:0)
如何在此列表中添加
IMyType<SubTypeImplementation>
?
IMyType
需要协变才能发挥作用。协变意味着泛型类型只能 包含在函数的输出中。由于您的界面包含EventHandler
,它将泛型类型作为输入的一部分,因此您的界面不能协变。
让我们更改您的界面名称以了解原因。假设你经营一个动物园,并希望区分&#34;仅查看&#34;来自&#34;正常&#34;的笼子笼子里。所以你有两个接口:
IViewOnlyCage<out T>
{
public T View();
}
ICage<T>
{
public Add(T animal);
}
现在考虑两个&#34;列表&#34;笼子:
List<IViewOnlyCage<IAnimal>> list1;
List<ICage<IAnimal>> list2;
我填写列表:
list1.Add(new Cage<Tiger>());
list1.Add(new Cage<Deer>());
在第一种情况下,只有视图的笼子列表是完全合理的。每个笼子都包含某种类型的动物,因此这两种动物没有危险结合在一起。
但考虑第二种方法 - 使用Add
方法,我可以这样做:
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>);
但实际泛型类型为SubTypeImplementation
,而非SecondSubType
,因此您遇到类型冲突。
最简单的更改似乎是将事件处理程序移动到另一个接口。然后,您可以IMyType
协变并拥有List<IMyType<IMySubType>>
。