C# 如何转换列表<;界面>;列出<;混凝土>;?
我有一个接口定义为:C# 如何转换列表<;界面>;列出<;混凝土>;?,c#,generics,interface,C#,Generics,Interface,我有一个接口定义为: public interface MyInterface { object foo { get; set; }; } 以及实现该接口的类: public class MyClass : MyInterface { object foo { get; set; } } 然后,我创建了一个返回ICollection的函数,如下所示: public ICollection<MyClass> Classes() { List<MyC
public interface MyInterface {
object foo { get; set; };
}
以及实现该接口的类:
public class MyClass : MyInterface {
object foo { get; set; }
}
然后,我创建了一个返回ICollection的函数,如下所示:
public ICollection<MyClass> Classes() {
List<MyClass> value;
List<MyInterface> list = new List<MyInterface>(
new MyInterface[] {
new MyClass {
ID = 1
},
new MyClass {
ID = 1
},
new MyClass {
ID = 1
}
});
value = new List<MyClass>((IEnumerable<MyClass>) list);
return value;
}
公共ICollection类(){
列表值;
列表=新列表(
新MyInterface[]{
新MyClass{
ID=1
},
新MyClass{
ID=1
},
新MyClass{
ID=1
}
});
值=新列表((IEnumerable)列表);
返回值;
}
它会编译,但会抛出一个
无法强制转换类型为的对象
'System.Collections.Generic.List1[MyInterface]'
打字
“System.Collections.Generic.IEnumerable
1[MyClass]”
例外。我做错了什么?通常不能将列表
转换为列表
,因为第一个列表可能包含实现MyInterface
的对象,但实际上不是MyClass
类型的对象
但是,由于您知道如何构造列表,并且可以确保它只包含MyClass
对象,因此可以使用Linq:
return list.ConvertAll(o => (MyClass)o);
但是列表
显然不是列表
思考:
interface IAnimal { }
class Cat : IAnimal { }
class Dog : IAnimal { }
var list = new List<IAnimal> { new Cat(), new Dog() };
荒谬
相反,你可以说
var cats = list.OfType<Cat>();
var cats=list.OfType();
我发现Automapper对于将接口转换为具体类非常有用 您可以使用Cast
扩展方法:
return list.Cast<MyClass>();
returnlist.Cast();
这是可能的,这就是泛型的闪光点!
下面是一个简单的例子:
public interface ICountable
{
int Count { get; set; }
}
public class PopularName : ICountable
{
public string Name { get; set; }
public int Count { get; set; }
}
public class PopularSize : ICountable
{
public int Size { get; set; }
public int Count { get; set; }
}
现在,您需要像下面这样声明您的方法(或类)泛型:
public bool HasAnyValue<T>(List<T> countableModel) where T : ICountable
{
return countableModel.Count > 0;
}
public bool HasAnyValue(List countableModel),其中T:i可数
{
返回countableModel.Count>0;
}
System.Collections.Generic.List直接支持ConvertAll()。谢谢,@Ritch。我原以为ConvertAll
是一个Linq方法,但我没有费心去检查。实际上,如果您确定列表中只包含MyClass
对象,您应该使用Enumerable.Cast
方法,如果序列中的某个元素无法强制转换为MyClass
@PaoloMoretti,您将获得InvalidCastException
,谢谢-您的方法节省了很多精力。我使用的是telerik wpf组件,在RadDataFilter中,返回值是一个接口列表,我必须对类型转换和字符串匹配开关以及if-else进行长时间的处理。现在我可以使用linq.:)我懂了。我很困惑,因为您可以将接口转换为它的具体类。谢谢。你能补充一些细节吗?
return list.Cast<MyClass>();
public interface ICountable
{
int Count { get; set; }
}
public class PopularName : ICountable
{
public string Name { get; set; }
public int Count { get; set; }
}
public class PopularSize : ICountable
{
public int Size { get; set; }
public int Count { get; set; }
}
public bool HasAnyValue<T>(List<T> countableModel) where T : ICountable
{
return countableModel.Count > 0;
}