Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.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#_Generics_Interface - Fatal编程技术网

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.List
1[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;
}