2014-09-04 2 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, чтобы принять аргумент независимо от типа супер класса T (TestA<>) есть, в случае TestB, что бы int.

Так что, если у меня была реализация типа TestC<TestB>, я хочу DoSomething подпись быть:

public TestB DoSomething(int argument); 

Проблема заключается в том, что TestA<X> не компилируется и не удается достичь этого


Возможно, вы знаете, если это возможно? Если да, не могли бы вы объяснить мне, как?

Может быть, я смогу что-то справиться с Reflection?

ответ

2

Вам просто нужно добавить общий аргумент для типа вы не хватает, в этом случае, X:

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

почему мы должны добавить его в '' TestC'', сделал 'nt получил это –

+0

Я не хочу добавлять его вручную и передавать его как общий аргумент, я хочу, чтобы компилятор заключил его :( –

+2

@MatiCicero Вы не можете этого сделать. Вам нужно указать его вручную. – Servy

-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); 
    } 
} 

Это один компилирует , но легко получить исключения во время выполнения из-за того, что IntelliSense не работает и выводит тип аргумента x.

Например, оба этих компиляций:

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

Но только первые один действительно должны работать, так как TestB наследует от TestA<int>

+0

1) Это не эквивалентный код, о котором просит ОП. 2) C# никогда не выведет некоторые, но не все общие аргументы. Это все или ничего. Ваше утверждение о том, что любой из этих примеров компиляции является ложным, по крайней мере для показанного кода. – Servy

+0

1) Это не эквивалентно, но это обходное решение для задачи компиляции ** и ** для того, что мне не нужно явно указывать тип моего параметра или аргумента –

+0

2) Код компилируется, хотя –

Смежные вопросы