2016-01-07 4 views
0

Я понимаю базовое наследование, и я понимаю основы дженериков..NET: определение определения класса

Но я не понимаю, это определение класса:

public class ExportController : AbstractFeedController<IExportFeed> 

В ExportController наследуется AbstractFeedController ...

но, что делает <IExportFeed> делать/в виду? Это что-то общего с дженериками?

+2

все будет становиться очень ясно, как только вы посмотрите на определение '' AbstractFeedController . – CodeCaster

+1

И поскольку есть около десяти тысяч потенциальных дубликатов, я не могу найти тот, который правильно объясняет это, поэтому не стесняйтесь отвечать на это, а также фрагментировать информацию на этом сайте еще больше. Все это объясняется в первых абзацах первого хита Google для «наследования на C# из базового базового класса»: [MSDN: общие классы (руководство по программированию на C#)] (https://msdn.microsoft.com/en-us /library/sz6zd40f.aspx). – CodeCaster

ответ

2

Да, это общее определение. Короче говоря, AbstractFeedController определяет общую реализацию, которая может применяться к различным типам, включая IExportFeed в вашем случае.

Посмотрите на определение класса AbstractFeedController, вы, вероятно, увидеть что-то вроде

class AbstractFeedController<T>{ ... 

В классе вы увидите тип T используется несколько раз. Всякий раз, когда вы видите это T, вы можете поменять его в своем уме любым типом, который, как вы думаете, может применяться.

В определении класса вы также можете увидеть where T : .... Это условие для типа T, ограничивающего типы типов, которые может использовать класс.

Прочитано this MSDN Article для подробного объяснения.

0

Унаследованный класс неявно определяет тип универсального класса.

Таким образом, унаследованный класс больше не является общим и использует базовый класс для предоставленного типа.

+0

_ "неявно определяет тип родового класса" _ - да, нет. Можете ли вы изменить это? Ключевое слово «построено родовым типом». – CodeCaster

4

An Introduction to C# Generics глава Inheritance and Generics:

При выводе из общего базового класса, вы должны предоставить аргумент типа вместо родового параметра типа базового класса:

public class BaseClass<T> 
{...} 
public class SubClass : BaseClass<int> 
{...} 

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

public class SubClass<T> : BaseClass<T> 
{...} 

Это означает, что ваш класс ExportController больше не родовой и является производным от класса AbstractFeedController<IExportFeed>.

2

В простом английском языке это означает, что ExportController является производным от закрытого типичного класса AbstractFeedController<IExportFeed>. AbstractFeedController класс имеет некоторые методы, свойства, поля, индексы и т. Д., Типы или типы возвращаемые или типы параметров которых могут иметь тип IExportFeed.

Так AbstractFeedController класс может выглядеть следующим образом

//This is a open type: 
public class AbstractFeedController <T> 
{ 
    T[] m_Items; 
    public void Feed(T item) 
    {...} 
    public T ReturnFeed() 
    {...} 
} 

Теперь мы закрываем тип, intansiating класс с IExportFeed в качестве параметра универсального типа

AbstractFeedController feedController = new AbstractFeedController<IExportFeed>(); 

Так класс внутренне переводится следующим образом:

//This is a closed type now: 
public class AbstractFeedController <IExportFeed> 
{ 
    IExportFeed[] m_Items; //Indexer type of IExportFeed 
    public void Feed(IExportFeed item) //A method accepting a parameter of type IExportFeed 
    {...} 
    public IExportFeed ReturnFeed() //A method returning type of IExportFeed 
    {...} 
} 
1

Представьте себе ситуацию, как

public class ExportController : IExportFeed 
public class ImportController : IImportFeed 

давайте предположим, что в экспорте случае мы имеем некоторые операции, общие для всех исполнителей IExportFeed. Таким образом, можно переместить эти операции в некоторый базовый абстрактный класс для иерархии IExportFeed. То же самое для IImportFeed.

Но что, если у нас есть общие операции для обеих этих иерархий? мы можем сделать что-то вроде

public abstract class ImportExportController : IExportFeed, IImportFeed

и наследовать экспорт или импорт классов от этого.

Но этот дизайн перерывы минимум пару ТВЕРДЫХ принципов, и это будет беспорядок, если вы решили добавить anoter подающие интерфейсы

Решение переместить эту общую между иерархии функциональных возможностей в родовое (шаблон)

public class ExportController : AbstractFeedController<IExportFeed> 
public class ImportController : AbstractFeedController<IImportFeed> 

и т.д.

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