2014-09-04 171 views
0

我知道标题可能有点混乱,但让我解释什么,我试图完成..推断类型泛型类


让我们假设我有

public class TestA<T> 
{ 
    public T Key { get; set; } 
} 

而且

public class TestB : TestA<int> 
{ 
    public string Name { get; set; } 
} 

正如你所看到的,TestB继承TestA<int>,因此继承了财产public int Key


现在,让我们添加一个接口

public interface TestC<T> where T : TestA<X> 
{ 
    T DoSomething(X argument); 
} 

这里的地方我有麻烦了。

我想DoSomething方法,采取任何类型的参数的超类的TTestA<>)时,在TestB的情况下,这将是int

所以,如果我有TestC<TestB>类型的实现,我想DoSomething签名是:

public TestB DoSomething(int argument); 

的问题是,TestA<X>不编译,我不能管理来实现这一


请问,你知道这是可能吗?如果是这样,你能解释一下吗?

也许我可以用反思

回答

2

你只需要添加你缺少的类型一般的参数,在这种情况下,X

public interface TestC<T, X> where T : TestA<X> 
{ 
    T DoSomething(X argument); 
} 
+0

为什么我们需要将其添加到''TestC'',做'nt得到它 – 2014-09-04 19:31:28

+0

我不想手动添加它并将它作为一个通用参数传递,我希望编译器推断它:( – 2014-09-04 19:31:32

+2

@MatiCicero你不能那样做,你需要手动指定它。 – Servy 2014-09-04 19:31:53

-1

有一个可能的解决方案过于:

public interface TestC { 
    T DoSomething<T,X>(X x) where T : TestA<X>; 
} 

public class TestCImpl : TestC { 
    public T DoSomething<T,X>(X x) where T : TestA<X> 
     //Do something 
     return default(T); 
    } 
} 

这一次编译但很容易得到运行时异常,因为智能感知似乎不起作用并推断出参数的类型。

例如,这两种编译的:

TestC c = new TestCImpl(); 
c.DoSomething<TestB>(2); 
c.DoSomething<TestB>("Hello"); 

但只有第一个应该真正发挥作用,为TestB继承TestA<int>

+0

1)这不等同于OP所要求的代码。 2)C#永远不会推断一些泛型参数,但不是全部。这是一个完全没有意义的事情。您断言这些示例中的任何一个编译都是错误的,至少对于显示的代码而言。 – Servy 2014-09-04 20:00:33

+0

1)它不是等价的,但它是编译问题**和**的解决方法,因为我不需要明确指定我的参数或参数的类型 – 2014-09-04 20:02:49

+0

2)代码确实编译,尽管 – 2014-09-04 20:03:48