我的界面定义为:
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;
}
它会编译,但会抛出
无法投射类型的对象 'System.Collections.Generic.List
1[MyInterface]' to type 'System.Collections.Generic.IEnumerable
1 [MyClass的]'。
异常。我做错了什么?
答案 0 :(得分:50)
一般来说List<MyInterface>
无法转换为List<MyClass>
,因为第一个列表可能包含实现MyInterface
但实际上不是MyClass
类型对象的对象
但是,因为在您的情况下,您知道如何构建列表并确保它只包含MyClass
个对象,您可以使用Linq执行此操作:
return list.ConvertAll(o => (MyClass)o);
答案 1 :(得分:32)
但List<MyInterface>
强调的不是List<MyClass>
。
想:
interface IAnimal { }
class Cat : IAnimal { }
class Dog : IAnimal { }
var list = new List<IAnimal> { new Cat(), new Dog() };
然后
var cats = (List<Cat>)list;
荒诞!
此外,
var cats = list.Cast<Cat>();
荒诞!
另外
var cats = list.ConvertAll(x => (Cat)x);
荒诞!
相反,你可以说
var cats = list.OfType<Cat>();
答案 2 :(得分:1)
您可以使用#!/usr/bin/env bash
TARGET_DIR=~/logs/docker_logs
mkdir -p "$TARGET_DIR"
for name in `sudo docker ps --format '{{.Names}}'`;
do
path=$(sudo docker inspect --format='{{.LogPath}}' $name)
sudo cp -rf "$path" "$TARGET_DIR"/$name.log
done
扩展方法:
Cast<>
答案 3 :(得分:1)
使用Cast如下:
list.Cast<T>().ToList()
答案 4 :(得分:0)
我发现Automapper对于将接口转换为具体类非常有用。
答案 5 :(得分:0)
这是可能的,这就是泛型的亮点! 这是一个简单的示例:
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;
}