c# - 一个用于连接具有相同接口(interface)的两个不同对象列表的衬垫

标签 c# .net linq generics interface

考虑这个简单的代码:

public interface Iinterface { }
public class Foo : Iinterface { }
public class Bar : Iinterface { }
[TestMethod()]
public void Test_Concat()
{
    var bars = new List<Bar>();
    var foos = new List<Foo>();
    // Ok
    IEnumerable<Iinterface> concats1 = bars.Cast<Iinterface>().Concat(foos.Cast<Iinterface>());
    // Compilation error
    IEnumerable<Iinterface> concats2 = bars.Concat(foos);
}

我想在一行中合并两个列表,并在编译时保持类型安全

例如,如果我删除类 Foo 的接口(interface),这仍然会编译,但在运行时失败:

public interface Iinterface { }
public class Foo { }
public class Bar : Iinterface { }
[TestMethod()]
public void Test_Concat()
{
    var bars = new List<Bar>();
    var foos = new List<Foo>();
    IEnumerable<Iinterface> concats1 = bars.Cast<Iinterface>().Concat(foos.Cast<Iinterface>());
}

如果我使用 OfType<T>() ,这不会在运行时失败,但我希望它在编译时失败。 我能找到的最好的方法是使用这 3 行代码:

var list = new List<Iinterface>();
list.AddRange(bars);
list.AddRange(foos);

但是对于这么简单的事情,我想找到一个单行,如果可能的话检索一个 IEnumerable<Iinterface>而不是 List<Iinterface> .
有什么办法可以实现吗?

最佳答案

你可以只写你自己的方法吗?

由于 IEnumerable 是协变的,因此您只需指定基数

var list= Combine<IInterface>(foos, bars);

private IEnumerable<T> Combine<T>(IEnumerable<T> ListA, IEnumerable<T> ListB)
{
    foreach (T t in ListA)
        yield return t;
    foreach (T t in ListB)
        yield return t;
}

虽然你也可以直接写

var list= foos.Concat<IInterface>(bars);

关于c# - 一个用于连接具有相同接口(interface)的两个不同对象列表的衬垫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15942716/

相关文章:

c# - 带有 Group By 和带有 Min(string) 的 Having 子句的 LINQ

c# - 如何在迭代时从通用列表中删除元素?

c# - 使用 linq 时如何最好地清理 SQLDataReader

c# - Entity Framework : Foreign Key in code first

.net - 升级到3.0.1后Nuget Assembly引用Microsoft Owin

.net - Azure Functions 中的程序集绑定(bind)重定向

C# 将函数作为参数传递

c# - struct 是将程序设置存储在内存中的好方法吗?

c# - 在 Entity Framework 中使用数学函数和 mysql

mysql - 如何为 linq 对象制作扁平化函数(Linq To Entities for mysql)?