setting/determining List<interface> 或 List<abstractClass> 中具体类型的最佳实践是什么?
What is the best practice for setting/determining the concrete types in a List<interface> or List<abstractClass>?
如果我有:
List<iCanSpeak>
或
List<Animal>
其中许多类型实现接口 iCanSpeak
或使用抽象 class Animal
作为基础 class.
determining/setting 我实际列表中的具体类型的最佳做法是什么?
我知道 C# 提供 .TypeOf
并且我看到了在基础 class 或接口中使用枚举的示例,以便更容易确定,但什么是最佳实践,为什么?
可能偏离主题的跟进:
此外,TypeOf
在幕后做什么?它正在铸造吗?为什么不同混凝土 class 的属性在放入 list<abstractClass>
时不会丢失?
是否...
List<AbstractClass> == List<interface>
定义的方法和属性是否相同?
您可以使用 .OfType<TSomeInterfaceOrClassOrAbstractClassOrStruct>()
扩展方法来 select 所有属于 iCanSpeak 类型或从其继承的列表成员。
在您的情况下,这可能是:MyList.OfType<ICanSpeak>()
。
一些参考文献:DotNetPearls and MSDN.
Does... List<AbstractClass> == List<interface>
If the defined methods and properties are the same?
没有。他们没有。由于列表是通用的 class,您不能将它们相互转换。您将需要一个 cast/convert 函数来为您执行此操作。
这可以是 .OfType<T>
过滤器,或者 .Cast<T>
returns 那个类型的新 IEnumerable
,或者 .Select(x => (yournewtype)x)
[=62] =] yournewtype
个 IEnumerable
。如果可能的话,我更喜欢.Cast<T>
(这种方法是为了将implementation
的列表转换为IInterfaceThatIsImplemented
的列表),否则如果你不需要所有成员,.OfType<T>
,但只有特定类型的。
示例:
var cars = new List<Car>();
var vehicles = cars.Cast<IVehicle>(); // works
var carsAndBicycles = new List<IVehicle>(); // think of some cars and bicycles in here
var otherCars = carsAndBicycles.OfType<Car>(); // works
var broken = carsAndBicycles.Cast<Car>(); // this breaks when carsAndBicycles doesnt only contain cars
// this is what .OfType<T> is useful for.
更深入 - 我上面写的不是很准确。
(来源:Jon Skeets Edulinq Implementation/Blog)
List<AbstractClass>
和List<interfaceThatIsImplementedInAbstractClass>
是一样的
不是在 C# 类中,编译器不允许,但 CLR 允许。
如果绕过编译器的检查,它就可以工作。
(我不推荐在任何理智的代码中使用那个“hack”!)
int[] ints = new int[10];
// Fails with CS0030
IEnumerable<uint> uints = (IEnumerable<uint>) ints;
// Succeeds at execution time
IEnumerable<uint> uints = (IEnumerable<uint>)(object) ints;
让我们玩得更开心:
int[] ints = new int[10];
if (ints is IEnumerable<uint>)
{
Console.WriteLine("This won’t be printed");
}
if (((object) ints) is IEnumerable<uint>)
{
Console.WriteLine("This will be printed");
}
如果我有:
List<iCanSpeak>
或
List<Animal>
其中许多类型实现接口 iCanSpeak
或使用抽象 class Animal
作为基础 class.
determining/setting 我实际列表中的具体类型的最佳做法是什么?
我知道 C# 提供 .TypeOf
并且我看到了在基础 class 或接口中使用枚举的示例,以便更容易确定,但什么是最佳实践,为什么?
可能偏离主题的跟进:
此外,TypeOf
在幕后做什么?它正在铸造吗?为什么不同混凝土 class 的属性在放入 list<abstractClass>
时不会丢失?
是否...
List<AbstractClass> == List<interface>
定义的方法和属性是否相同?
您可以使用 .OfType<TSomeInterfaceOrClassOrAbstractClassOrStruct>()
扩展方法来 select 所有属于 iCanSpeak 类型或从其继承的列表成员。
在您的情况下,这可能是:MyList.OfType<ICanSpeak>()
。
一些参考文献:DotNetPearls and MSDN.
Does...
List<AbstractClass> == List<interface>
If the defined methods and properties are the same?
没有。他们没有。由于列表是通用的 class,您不能将它们相互转换。您将需要一个 cast/convert 函数来为您执行此操作。
这可以是 .OfType<T>
过滤器,或者 .Cast<T>
returns 那个类型的新 IEnumerable
,或者 .Select(x => (yournewtype)x)
[=62] =] yournewtype
个 IEnumerable
。如果可能的话,我更喜欢.Cast<T>
(这种方法是为了将implementation
的列表转换为IInterfaceThatIsImplemented
的列表),否则如果你不需要所有成员,.OfType<T>
,但只有特定类型的。
示例:
var cars = new List<Car>();
var vehicles = cars.Cast<IVehicle>(); // works
var carsAndBicycles = new List<IVehicle>(); // think of some cars and bicycles in here
var otherCars = carsAndBicycles.OfType<Car>(); // works
var broken = carsAndBicycles.Cast<Car>(); // this breaks when carsAndBicycles doesnt only contain cars
// this is what .OfType<T> is useful for.
更深入 - 我上面写的不是很准确。
(来源:Jon Skeets Edulinq Implementation/Blog)
List<AbstractClass>
和List<interfaceThatIsImplementedInAbstractClass>
是一样的
不是在 C# 类中,编译器不允许,但 CLR 允许。
如果绕过编译器的检查,它就可以工作。
(我不推荐在任何理智的代码中使用那个“hack”!)
int[] ints = new int[10]; // Fails with CS0030 IEnumerable<uint> uints = (IEnumerable<uint>) ints; // Succeeds at execution time IEnumerable<uint> uints = (IEnumerable<uint>)(object) ints;
让我们玩得更开心:
int[] ints = new int[10]; if (ints is IEnumerable<uint>) { Console.WriteLine("This won’t be printed"); } if (((object) ints) is IEnumerable<uint>) { Console.WriteLine("This will be printed"); }