2015-02-05 3 views
9

Скажем, у меня есть следующий C# интерфейс:Почему общий класс, реализующий общий интерфейс с ограничениями типа, должен повторять эти ограничения?

public interface IInterface<T> where T : SomeClass 
{ 
    void InterfaceMethod(); 
} 

И SomeClass определяется следующим образом:

public class SomeClass 
{ 
    public void SomeMethod(); 
} 

Теперь я хотел бы определить реализацию интерфейса, который не компилируется :

public class InterfaceImpl<T> : IInterface<T> 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Gives Error 
    } 
} 

, прежде чем изменить его на:

public class InterfaceImpl<T> : IInterface<T> where T : SomeClass 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Compiles fine 
    } 
} 

Не имеет ли смысл, что ограничения типа также «унаследованы» (а не правильное слово, я знаю) из интерфейса?

+1

Возможно, они были реализованы «по умолчанию», если ничего не указано. Но фактический синтаксис позволяет переопределить ограничения (наследование, новое() ключевое слово и т. Д.), Что хорошо. – AFract

ответ

9

Класс не должен повторять эти ограничения, ему необходимо указать тип, который удовлетворяет ограничениям интерфейса. Есть несколько способов сделать это:

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

Главное, что T в InterfaceImpl<T> принадлежит InterfaceImpl, поэтому независимо от ограничений, которые размещаются на T должны быть InterfaceImpl «s собственный.

+0

Очень хорошее и ясное объяснение, последнее предложение было для меня решающим :) Зная ваш ответ, единственное, что я не понимаю, - это то, почему C# позволит мне создать класс, который не выполняет никаких действий, упомянутых в вашем ответ? Скажем, это какой-то абстрактный класс, который не вызывает методы T - я могу скомпилировать его без каких-либо ограничений на T или указав тип, который бы удовлетворял ограничениям интерфейса. –

+1

@BartekEborn Я не уверен, что вы имеете в виду. В ситуациях, когда общий интерфейс имеет ограничение, реализующий его класс должен предоставлять совместимый параметр независимо от того, является ли класс реализации абстрактным или нет ([demo - не компилируется] (http://ideone.com/WG9pR1)). Я уверен, что вы имели в виду что-то еще. Можете ли вы сделать демоверсию, которая показывает, что вы имеете в виду? Вы можете нажать «fork» в моей демонстрации и изменить ее, если хотите. – dasblinkenlight

+0

Это именно то, что я имел в виду. Мне плохо, я сожалею о твоих усилиях. Я доверял Intellisense, который не выделял ошибку в таком случае (хотя это было и в предыдущем). После того, как я испытал это, мне стало стыдно :(Еще раз! –

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