简体   繁体   English

演员表 <string> 到MyClass <object> 运行时失败

[英]Cast MyClass<string> to MyClass<object> fails in runtime

In developing a class that should handle various generic lambda expressions, I fell into a rather familiar hole: I had a MyClass<T> class, and I tried to cast MyClass<string> to MyClass<object> , like so: 在开发应该处理各种通用lambda表达式的类时,我陷入了一个相当熟悉的漏洞:我拥有MyClass<T>类,并且试图将MyClass<string> MyClass<object>MyClass<object> ,如下所示:

MyClass<string> myClassString = GetMyClass(); // Returns MyClass<String>
MyClass<object> myClassObject = myClassString;

Doing so returned an compilation error saying there there's no implicit conversion between the two types, but that an explicit conversion does exist. 这样做会返回一个编译错误,指出这两种类型之间没有隐式转换,但确实存在显式转换。 So I added the explicit conversion: 因此,我添加了显式转换:

MyClass<object> myClassObject = (MyClass<object>)myClassString;

Now the code compiled, but failed in runtime, claiming the conversion is illegal. 现在,代码已编译,但在运行时失败,声称转换是非法的。

I am using Visual Studio 2012, and the code is part of a Portable Class Library project compiled with C# 5. 我正在使用Visual Studio 2012,并且代码是使用C#5编译的可移植类库项目的一部分。

Just to make sure, I replaced MyClass IList - the same behavior appeared - an explicit conversion is allowed, but fails during run-time. 为了确保,我替换了MyClass IList出现了相同的行为-允许显式转换,但在运行时失败。

Why? 为什么? Why does the compiler accept this? 编译器为什么接受这个? What's the point of the explicit conversion if it fails in runtime? 如果显式转换在运行时失败,那有什么意义呢?

In order to allow the cast, you need to mark it as covariant. 为了允许强制转换,您需要将其标记为协变。 However, covariance is only allowed for interfaces (and delegates). 但是,协方差仅适用于接口(和委托)。 This would look like: 看起来像:

interface MyInterface<out T> ...

The reason why you can compile the explicit cast is probably that the compiler assumes that the return value of GetMyClass() could be a MyClass<object> . 之所以可以编译显式GetMyClass() ,可能是因为编译器假定GetMyClass()的返回值可以是MyClass<object> But That's hard to say without the declaration. 但是,如果没有声明,这很难说。

To be able to cast MyClass<string> to MyClass<object> you need to fulfill the following: 为了能够将MyClass<string> MyClass<object>MyClass<object>您需要满足以下条件:

  • MyClass<T> must be an interface, eg IMyClass<T> . MyClass<T>必须是接口,例如IMyClass<T>
  • You need to add the out keyword to the type parameter T , making the type parameter covariant . 您需要将out关键字添加到类型参数T ,以使类型参数为协变
  • The type parameter T may only appear in output positions of the members of the interface. 类型参数T只能出现在接口成员的输出位置。

For example: 例如:

public interface IMyClass<out T>
{
    T GetItem();    // T in an output position
}

Now you can cast it: 现在您可以投射它:

IMyClass<string> myClassString;
IMyClass<object> myClassObject = (IMyClass<object>)myClassString;

If you have classes A and B and you want to cast B to A then one of the following must be true: 如果您具有A和B类,并且要将B强制转换为A,则以下条件之一必须为真:

  • B derives/implements A or vice versa B派生/实现A,反之亦然
  • There is an explicit cast operator defined from B to A 从B到A定义了一个显式强制转换运算符

None of the above is true in your case so the cast is invalid. 以上情况都不符合您的情况,因此强制转换无效。

If your class implements IEnumerable you may use an extension method 如果您的类实现IEnumerable,则可以使用扩展方法

using System.Linq
...
MyClass<Object> asObject = GetMyClass().Cast<Object>();

Otherwise, write an explicit operator or function that does the conversion: 否则,编写执行转换的显式运算符或函数:

public MyClass<Base> ConvertToBase<Base, Derived>(MyClass<Derived>) where Derived : Base
{
    // construct and return the appropriate object
}

为什么我不能从列表中投射<myclass>列出<object> ?<div id="text_translate"><p> 我有一个对象列表,它们属于我的QuoteHeader类型,我想将此列表作为对象列表传递给能够接受List&lt;object&gt;的方法。</p><p> 我的代码行显示...</p><pre> Tools.MyMethod((List&lt;object&gt;)MyListOfQuoteHeaders);</pre><p> 但是我在设计时收到以下错误...</p><pre> Cannot convert type 'System.Collections.Generic.List&lt;MyNameSpace.QuoteHeader&gt;' to 'System.Collections.Generic.List&lt;object&gt;'</pre><p> 我需要对我的 class 做任何事情来允许这样做吗? 我认为所有类都继承自 object 所以我不明白为什么这不起作用?</p></div></object></myclass> - Why can't I cast from a List<MyClass> to List<object>?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何投射词典 <string,MyClass> 到字典 <string,object> - How to cast Dictionary<string,MyClass> to Dictionary<string,object> 投射我的课堂<T>到我的课堂<dynamic> - Cast MyClass<T> to MyClass<dynamic> 演员表 <object> 列表 <myclass> C# - Cast List<object> to List<myclass> c# 创建类型“ MyClass:OtherClass <MyClass> {}”在运行时? - Create type “MyClass : OtherClass<MyClass> { }” at runtime? 复制ObservableCollection <myclass> 到ObservableCollection <KeyValuePair<string,object> &gt; - Copy ObservableCollection<myclass> to ObservableCollection<KeyValuePair<string,object>> 当T是IEnumerable <U>时,myClass <T>的隐式强制转换失败 - Implicit cast fails for myClass<T> when T is IEnumerable<U> 为什么使用反序列化方法正确构造的对象有一个失败测试是 Myclass ? 还是作为 MyClass 演员表? - why a object correctly construct with deserialize method have a failure test is Myclass ? or as MyClass cast? 铸造MyClass <T> 到MyClass <object> C# - Casting MyClass<T> to MyClass<object> C# 为什么我不能从列表中投射<myclass>列出<object> ?<div id="text_translate"><p> 我有一个对象列表,它们属于我的QuoteHeader类型,我想将此列表作为对象列表传递给能够接受List&lt;object&gt;的方法。</p><p> 我的代码行显示...</p><pre> Tools.MyMethod((List&lt;object&gt;)MyListOfQuoteHeaders);</pre><p> 但是我在设计时收到以下错误...</p><pre> Cannot convert type 'System.Collections.Generic.List&lt;MyNameSpace.QuoteHeader&gt;' to 'System.Collections.Generic.List&lt;object&gt;'</pre><p> 我需要对我的 class 做任何事情来允许这样做吗? 我认为所有类都继承自 object 所以我不明白为什么这不起作用?</p></div></object></myclass> - Why can't I cast from a List<MyClass> to List<object>? Cast IList <string> 到IList <object> 在运行时失败 - Cast IList<string> to IList<object> fails at runtime
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM