2013-11-20 7 views
0

У меня есть вопрос о дженериков и использование интерфейсов отданных при создании Concret классов:Общий интерфейс ограничение


namespace MyNamespace 
{ 
    interface ITest 
    { 

    } 

    class Timpl : ITest 
    { 

    } 

    class Test<T> where T : ITest 
    { 
     public T get() 
     { 
      return default(T); 
     } 
    } 

    class MyClass 
    { 
     public MyClass() 
     { 
      Test<ITest> s = new Test<Timpl>(); //Does not compile 
     } 
    } 
} 

Я читал на ко- и контравариантных, но я должен быть что-то отсутствует, или это не имеет ничего делать то, что я пытаюсь, или просто не работает то, что я пытаюсь сделать.

Хотя я мог бы сделать актерский состав от Test to Test, потому что TImple наследуется от ITest.

+0

Вы не нашли какой-либо из предоставленных ответов полезные? Не забудьте отметить его как принятый, проверив зеленую метку ниже ответа. –

ответ

0

Я думаю, что я понимаю вашу проблему. Вы можете прочитать о ковариации и контрвариации по следующей ссылке MSDN: http://msdn.microsoft.com/en-us/library/vstudio/ee207183.aspx

Мое решение вашей проблемы выглядит так

интерфейс ITEST { }

class TImpl:ITest 
{ 

} 

interface ITest<out T> 
{ 
    T get(); 
} 

class Test<T>:ITest<T> 
      where T:ITest 
{ 
    public T get() 
    { 
     return default(T); 
    } 
} 

Как вы можете видеть, я» ve добавил и интерфейс через ваш тестовый класс, и я пометил аргумент Type, T, как out. Теперь вы можете сделать следующее:

ITest<ITest> t = new Test<TImpl>(); 

Я надеюсь, что это помогает

3

Это должно быть

class Test<T> where T : ITest 
{ 
    public T get() 
    { 
     return default(T); 
    } 
} 

Затем создайте экземпляр Test как

var s = new Test<Timpl>(); 

EDIT:

Основываясь на комментарий ниже. Хорошо, теперь вы имеете дело с ковариацией и контравариантностью. Если вам нужно указать

Test<ITest> s = new Test<Timpl>(); 

, то он не может работать, потому что только общие параметры типа интерфейсов и делегатов могут быть помечены как ковариантный или контравариантный.

Однако, вы можете решить это, сделав Test реализовать интерфейс.

interface ITestClass<out T> 
{ 
    T get(); 
} 

class Test<T> : ITestClass<T> where T : ITest 
{ 
    public T get() 
    { 
     return default(T); 
    } 
} 

ITestClass<ITest> s = new Test<Timpl>(); // Does compile 
+0

Извините, но не заметил, что он не писал теги morethen и lessthen. Таким образом, пример сейчас немного отличается. – MazeezaM

+0

@ MazeezaM Я обновил свой ответ. –

+0

Добавлено рабочее решение. –

1

попробуйте это.

namespace MyNamespace 
{ 
    interface ITest 
    { 
    } 

    class Timpl : ITest 
    { 
    } 

    class Test<T> where T : ITest 
    { 
     public T get() 
     { 
      return default(T); 
     } 
    } 

    public class mycls : ITest 
    { 
    } 

    class MyClass 
    { 
     public MyClass() 
     { 
      Test<mycls> s = new Test<mycls>(); //will compile 
     } 
    } 
} 
+0

Зачем создавать 'mycls', когда OP уже имеет реализацию' ITest'? Кажется, он просто не знает, как его использовать. –

+0

Извините, но не заметил, что он не писал теги morethen и lessthen. Таким образом, пример сейчас немного отличается. – MazeezaM

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