这是为什么投不可能的? [英] Why is this cast not possible?
问题描述
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屋!