我必须诚实地说,我对铸造并不是很了解,但我认为这样可行。
我有一个通用课程测试:
public class Test<T,U>
{
T variable1;
U variable2;
//etc.
}
我需要在WPF视图中使用这个类,因为你不能在WPF中创建通用视图(多么可爱)我想:让我们使用Test<object, object
&gt;对于视图,因为我只关心在视图中使用变量的字符串表示。
所以我试试:
Test<Foo, Bar> test = new Test<Foo, Bar>();
return test as Test<object, object>;
但这给了我:
Error 1 Cannot convert type 'DomainModel.Tests.Test<T,U>'
to 'DomainModel.Tests.Test<object,object>' via a reference conversion, boxing
conversion, unboxing conversion, wrapping conversion, or null type conversion
我认为每个对象都必须可以转换为对象?
无论如何,我现在很困惑如何在WPF中使用泛型类......
任何指针都在正确的方向?
答案 0 :(得分:5)
这是一个通用的差异问题。 C#3不允许通用参数类型的差异:因此,IEnumerable<string>
与IEnumerable<object>
不兼容。对于C#4中的安全方案,将放宽此限制。但这对您的情况没有帮助,因为C#4仅支持接口或委托的差异。即使C#的未来版本允许类的泛型差异,仍然可能无法帮助您,因为Test<object, object>
是安全的强制转换并不清楚:假设variable1有一个setter:
Test<string, string> t = new Test<string, string>();
Test<object, object> bad_t = t as Test<object, object>;
bad_t.variable1 = new Llama(); // but variable1 should contain only strings!
然而,您可以将“Test<string, string>
”投射到object
:
object good_t = t; // don't even need a cast
WPF绑定仍然可以通过反射访问其属性。
或者,定义一个非泛型接口,提供您需要的功能(在您的情况下为“变量的字符串表示”):
public interface IPresentV1AndV2 // stupid name of course
{
public string Variable1AsString { get; }
public string Variable2AsString { get; }
}
并在您的泛型类上实现此功能。然后,您可以通过接口成员访问字符串值。 (显然,这个特定的接口示例是愚蠢地绑定到实现,实际上你会给它一个名称和成员,反映它暴露的数据的业务含义。)
答案 1 :(得分:3)
版本3.0的C#不支持通用协同/反向差异。也就是说,IEnumerable<string>
之类的内容与IEnumerable<object>
不兼容。
C#4引入了静态检查定义网站安全通用协同/反差 - 但它也不会对你有所帮助。它要求通用参数仅用于输入或输出位置,但不能同时用于两者。也就是说,List<string>
与C#4.0中的List<object>
不兼容,但IEnumerable<string>
可用作IEnumerable<object>
,因为IEnumerable
的类型参数仅用作Current
属性的返回值(输出位置)。