【问题标题】:c# casting questionc# 铸造问题
【发布时间】:2010-01-10 16:24:54
【问题描述】:

如果我有以下课程:

public class MyItems : List<MyItem>
{
..
}

public class MyItem : Item
{
..
}

我如何才能将 MyItems 的实例转换回 List&lt;Item&gt;?我尝试进行显式强制转换,但出现异常。

【问题讨论】:

  • 在 C# 4 中,您可以将其转换为 IEnumerable,但不能转换为 IList

标签: c# casting


【解决方案1】:

你不能,因为 C# 不支持泛型变量 (see here for discussion of terminology),即使支持,它也不会允许这种情况,因为如果你可以将 MyItems 转换为 List&lt;Item&gt;,你可以调用Add(someItemThatIsntAMyItem),这将违反类型安全(因为 MyItems 只能包含 MyItem 对象,不能包含任意项)。

请参阅this question(或在 SO 中搜索“c# generic variance”)以获取有关此问题和 C# 4 未来更改的更多信息(尽管这些不会影响您的具体情况)。

【讨论】:

  • 感谢您的解释。我想出了一个不同的设计来得到我需要的东西。
【解决方案2】:

我相信我看到了 4.0 的到来。尚不可用。

【讨论】:

  • 不,不会出现在 4.0 中,因为 (a) C# 4 仅支持代表和接口的变化,而不支持类(叹气)和 (b) 即使它确实支持类的变化,它对List&lt;T&gt; 来说是不安全的,因为 T 是 in-out(仅当类型参数仅作为输入或仅作为输出出现时,方差才是安全的,而不是同时出现)。
【解决方案3】:
public class MyList : IList<MyClass>
{
    List<MyClass> _list;


    //Implement all IList members like so
    public int IndexOf(MyClass item)
    {
        return _list.IndexOf(item);
    }


    //Then help the type system a bit with these two static methods.
    public static implicit operator List<MyClass> (MyList mylist)
    {
        return mylist._list;
    }

    public static implicit operator MyList (List<MyClass> list)
    {
        return new MyList() { _list = list;}
    }

【讨论】:

    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 2021-01-16
    • 2023-04-04
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    相关资源
    最近更新 更多