【问题标题】:c# How to cast to IList<SomeInterface> and back to IList<MyOBject> [duplicate]c# 如何转换为 IList<SomeInterface> 并返回 IList<MyOBject> [重复]
【发布时间】:2019-11-23 13:42:36
【问题描述】:

考虑以下代码:

public interface ITest
{
    public string Id { get; set; }
}

public class MyObject : ITest {
{
    public string Id { get; set; }
    public string Value { get; set; }
}

public void Run()
{
    IList<MyOBject> myObjects = GetMyObjects();

    myObjects = GetTestITems(myObjects);
}

public IList<ITest> GetTestItems(IList<ITest> items)
{
    //run some logic
    return items;
}

上面的代码会失败两次。第一次是尝试将IList&lt;MyObject&gt; 转换为IList&lt;ITest&gt;,然后尝试转换回IList&lt;MyObject&gt;。但是,如果我将代码更改为以下代码,则它可以工作:

public void Run()
{
    IList<MyOBject> myObjects = GetMyObjects();
    var myTests = new List<ITest>();

    foreach(var o in myObjects) {
        myTests.Add(o);
    }

    var result = GetTestITems(myTests);
    myObjects = new List<MyObject>();

    foreach(var r in result) {
        myObjects.Add(r);
    }
}

有没有一种方法可以实现这一点而不必像这样循环两次?也许是一种 linq 方式或某种形式的铸造?我尝试过直接强制转换,但在两个实例上都失败了,转到 ITest 并返回到 MyObject。

【问题讨论】:

  • 你能用 IEnumerable 代替 IList 吗?
  • @user1781290 在哪个部分?
  • 如果你可以将 public IList GetTestItems(IList items) 更改为 public IEnumerable GetTestItems(IEnumerable items) 你应该没问题。如果没有,您需要创建一个新列表
  • 如果您可以使用IReadOnlyList&lt;T&gt; 作为GetTestItems() 的参数,那将解决您一半的担忧。另一半是棘手的,原因在涉及类型参数差异的大量现有 Stack Overflow 帖子中进行了解释,包括标记的重复项(在网站上有一些更广泛的解释)。当类型参数 T 不同时,即使从 IReadOnlyList&lt;T&gt; 回退也根本不是类型安全的,更不用说 IList&lt;T&gt;
  • 同意@PeterDuniho。在T 中使用协变(“out”)的IReadOnlyList&lt;out T&gt; 免费获得安全转换。你不能做的不安全的方式。如果您坚持,您可以将.Cast&lt;MyObject&gt;() 用作不同的语法,但它仍然会遍历列表,并且当/如果您遇到恰好不是MyObjectITest 时它会爆炸。

标签: c# linq interface casting


【解决方案1】:

我认为在这种情况下您需要使用泛型,如下所示:

public interface ITest
{
    public string Id { get; set; }
}

public class MyObject : ITest {
{
    public string Id { get; set; }
    public string Value { get; set; }
}

public void Run()
{
    List<MyOBject> myObjects = new List<MyOBject>(); // With your objects

    myObjects = GetTestItems<MyOBject>(myObjects);
}

public IList<T> GetTestItems<T>(IList<T> items)
where T : ITest
{
    //run some logic with props of ITest
    return items;
}

【讨论】:

  • 您不必在GetTestItems 调用中指定类型,因为它将通过将myObjects 作为items 参数传递来推断。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多