C#(+ WPF)将泛型类转换为非泛型的问题

Pet*_*rdk 2 c# generics casting

我必须诚实地说,我对铸造并不是很了解,但我认为这样可行.

我有一个通用类测试:

public class Test<T,U>
{
     T variable1;
     U variable2;

     //etc.
}
Run Code Online (Sandbox Code Playgroud)

我需要在WPF视图中使用这个类,因为你不能在WPF中创建通用视图(多么可爱)我想:让我们只使用一个Test<object, object>视图,因为我只关心使用字符串表示视图中的变量.

所以我尝试:

  Test<Foo, Bar> test = new Test<Foo, Bar>();
  return test as Test<object, object>;
Run Code Online (Sandbox Code Playgroud)

但这给了我:

  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
Run Code Online (Sandbox Code Playgroud)

我认为每个对象都必须可以转换为对象?

无论如何,我现在很困惑如何在WPF中使用泛型类...

任何指针都在正确的方向?

ito*_*son 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!
Run Code Online (Sandbox Code Playgroud)

但是你可以"施放" Test<string, string>object:

object good_t = t;  // don't even need a cast
Run Code Online (Sandbox Code Playgroud)

WPF绑定仍然可以通过反射访问其属性.

或者,定义一个非泛型接口,提供您需要的功能(在您的情况下为"变量的字符串表示"):

public interface IPresentV1AndV2  // stupid name of course
{
  public string Variable1AsString { get; }
  public string Variable2AsString { get; }
}
Run Code Online (Sandbox Code Playgroud)

并在您的泛型类上实现它.然后,您可以通过接口成员访问字符串值.(显然,这个特定的接口示例是愚蠢地绑定到实现,实际上你会给它一个名称和成员,反映它暴露的数据的业务含义.)