这是为什么投不可能的? [英] Why is this cast not possible?

查看:94
本文介绍了这是为什么投不可能的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

interface IFolderOrItem<TFolderOrItem> where TFolderOrItem : FolderOrItem {}

abstract class FolderOrItem {}

class Folder : FolderOrItem {}

abstract class Item : FolderOrItem {}

class Document : Item {}

现在我想做某事是这样的:

now i'm trying to do sth like this:

class Something
{
    IFolderItemOrItem<Item> SelectedItem { get; set; }
    void SomeMagicMethod()
    {
        this.SelectedItem = (IFolderOrItem<Item>)GetMagicDocument();
        // bad bad bad ... ??
    }
    IFolderOrItem<Document> GetMagicDocument()
    {
        return someMagicDocument; // which is of type IFolderOrItem<Document>
    }
}

是否有可能得到这个工作?

is there any possibility to get this working?

推荐答案

如果我正确地读它...那么问题是,仅仅因为富:酒吧,即做的不可以意味着 ISomething&LT;富&GT; :ISomething&LT;酒吧GT; ...

If I read it correctly... then the problem is that just because Foo : Bar, that does not mean that ISomething<Foo> : ISomething<Bar>...

在一些情况下,方差在C#4.0可能是一种选择。另外,有时有事情,你可以用普通的方法做(不知道它会帮助在这里,虽然)。

In some cases, variance in C# 4.0 may be an option. Alternatively, there are sometimes things you can do with generic methods (not sure it will help here, though).


最近,你可以做C(下方)#3.0可能是一个非通用基本接口:

The closest you can do in C# 3.0 (and below) is probably a non-generic base interface:

interface IFolderOrItem {}
interface IFolderOrItem<TFolderOrItem> : IFolderOrItem
    where TFolderOrItem : FolderOrItem { }

常用,基本的界面会有,例如<​​code>键入的ItemType {获得;} 来表示所考虑的真正类型。然后用法:

commonly, the base-interface would have, for example, a Type ItemType {get;} to indicate the real type under consideration. Then usage:

IFolderOrItem SelectedItem { get; set; }
...
public void SomeMagicMethod()
{
    this.SelectedItem = GetMagicDocument(); // no cast needed
    // not **so** bad
}



从规范,这涉及到§25.5.6(ECMA 334第4版):

From the spec, this relates to §25.5.6 (ECMA 334 v4):

25.5.6转换

构造类型遵循相同的转换规则(§13)
  因为这样做非泛型类型。当应用
  这些规则,基类和
  构造类型的接口应
  如§25.5.3所描述的决定。

Constructed types follow the same conversion rules (§13) as do non-generic types. When applying these rules, the base classes and interfaces of constructed types shall be determined as described in §25.5.3.

之间不存在特别的转换
  比其他构造引用类型
  那些§13描述。尤其是,
  不像数组类型,构造
  引用类型不允许
  合变转换(§19.5)。这个
  是指一个类型列表&LT; B&GT;
  转换(隐式或
  明确),以列表&LT; A&GT; 即使 B
  从 A衍生。同样地,无
  转化率从存在列表&LT; B&GT;
  列表与LT;对象&gt;

No special conversions exist between constructed reference types other than those described in §13. In particular, unlike array types, constructed reference types do not permit co-variant conversions (§19.5). This means that a type List<B> has no conversion (either implicit or explicit) to List<A> even if B is derived from A. Likewise, no conversion exists from List<B> to List<object>.

[注:为理由
  这很简单:如果一个转换
  列表与LT; A&GT; 是允许的,那么很显然,
  可以键入 A 的值保存到
  列表。然而,这将破坏
  不变,每一个对象
  B&GT;键入名单,LT的列表始终是一个值
  类型 B ,否则意外故障
  分配到时,会发生
  集合类。注完]

[Note: The rationale for this is simple: if a conversion to List<A> is permitted, then apparently, one can store values of type A into the list. However, this would break the invariant that every object in a list of type List<B> is always a value of type B, or else unexpected failures can occur when assigning into collection classes. end note]

这同样适用于接口。这会改变的的在C#4.0,但只在某些情况下。

The same applies to interfaces. This changes a bit in C# 4.0, but only in some cases.

这篇关于这是为什么投不可能的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆