我试图在他们创建的疯狂情况下向某人展示接口的用途.它们在列表中有几个不相关的对象,需要对每个对象中的两个字符串属性执行操作.我指出,如果他们将属性定义为接口的一部分,他们可以使用接口对象作为作用于它的方法参数的类型; 例如:
void PrintProperties(IEnumerablelist) { foreach (var item in list) { Console.WriteLine("{0} {1}", item.Prop1, item.Prop2); } }
这似乎一切都很好,但是需要处理的列表不是(也不应该)使用接口作为类型参数声明.但是,您似乎无法转换为其他类型参数.例如,这失败了,我无法理解为什么:
using System; using System.Collections.Generic; namespace ConsoleApplication2 { class Program { static void Main(string[] args) { ListmyList = new List (); for (int i = 0; i < 5; i++) { myList.Add(new Test()); } PrintList((IEnumerable )myList); } static void PrintList(IEnumerable list) { foreach (IDoSomething item in list) { item.DoSomething(); } } } interface IDoSomething { void DoSomething(); } public class Test : IDoSomething { public void DoSomething() { Console.WriteLine("Test did it!"); } } }
我可以使用该Enumerable.Cast
成员执行此操作,但我一直在寻找可能在.NET 2.0中工作的方法.看来这应该是可能的; 我错过了什么?
问题在于方法,而不是如何被称为......
void PrintProperties(IEnumerable list) where SP: ISpecialProperties { foreach (var item in list) { Console.WriteLine("{0} {1}", item.Prop1, item.Prop2); } }
它失败的原因是因为泛型不会在C#中表现出差异(尚未).
至于IEnumerable
public static IEnumerableSafeConvert (IEnumerable source) where TDerived : TBase { foreach (TDerived element in source) { yield return element; // Implicit conversion to TBase } }
编辑:对于这种特殊情况,其他现有答案比上面的更好,但是如果你确实需要"转换"序列,我会把它留在这里作为一个普遍有用的东西.