将列表<t>转换为列表<interface> </interface> </t>

时间:2012-01-19 11:38:11

标签: c# .net interface casting

public interface IDic
{
    int Id { get; set; }
    string Name { get; set; }
}
public class Client : IDic
{

}

如何将List<Client>投射到List<IDic>

8 个答案:

答案 0 :(得分:205)

你不能施放它(保留参考标识) - 这是不安全的。例如:

public interface IFruit {}

public class Apple : IFruit {}
public class Banana : IFruit {}

...

List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());

// Eek - it's a banana!
Apple apple = apples[0];

现在,由于协方差,您可以在.NET 4 / C#4中将List<Apple>转换为IEnumerable<IFruit>,但如果您想要List<IFruit>,则必须创建列表。例如:

// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();

// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();

但这与投射原始列表相同 - 因为现在有两个单独的列表。这是安全的,但您需要了解对一个列表所做的更改不会在另一个列表中看到。 (当然,将会看到列表引用的对象的修改。)

答案 1 :(得分:5)

Cast iterator和.ToList():

List<IDic> casted = input.Cast<IDic>().ToList()可以解决问题。

最初我说协方差会奏效 - 但正如乔恩正确指出的那样;不,它不会!

最初我还愚蠢地离开了ToList()电话

答案 2 :(得分:4)

我也有这个问题,在阅读Jon Skeet的回答后,我修改了我的代码,使用List<T>来使用IEnumerable<T>。虽然这不符合OP的原始问题如何将List<Client>投射到List<IDic> ,但它确实避免了这样做,因此可能会有所帮助对遇到此问题的其他人。当然,这假定需要使用List<IDic>的代码由您控制。

E.g:

public void ProcessIDic(IEnumerable<IDic> sequence)
{
   // Implementation
}

而不是:

public void ProcessIDic(List<IDic> list)
{
   // Implementation
}

答案 3 :(得分:2)

如果您可以使用LINQ,那么您可以这样做......

List<Client> clientList = new List<Client>();
List<IDic> list = clientList.Select(c => (IDic)c).ToList();

答案 4 :(得分:2)

List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();

答案 5 :(得分:0)

只有通过创建新的List<IDic>并传输所有元素才能实现。

答案 6 :(得分:0)

在.Net 3.5中,您可以执行以下操作:

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());

在这种情况下,List的构造函数采用IEnumerable。
列表虽然只能转换为IEnumerable。即使 myObj 可以转换为ISomeInterface,IEnumerable类型也无法转换为IEnumerable。

答案 7 :(得分:0)

OfType

您可以尝试类似的操作:

        using (var dbContext = YourDatabaseContext())
        {
            var list = dbContext.Clients.Where(x => x.Happy)
                .OfType<IDic>()
                .ToList();
        }

请参见https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.oftype