2014-09-14 3 views
1

У меня есть иерархия классов вроде следующего:общие типы и наследование спутанность

public class Country : MainObj 
public class MainObj : BaseEntity 

и у меня есть бизнес-логики классов, как следующее:

public class CountryBLL<TEntity> : CountryDLL<TEntity>,IBaseBLL<TEntity> where TEntity : Country 
public class MainObjBLL<TEntity> : MainObjDLL<TEntity>, IBaseBLL<TEntity> where TEntity : MainObj 

Теперь вещь, которую я хочу осуществить это функция, в которой я решаю, какой класс и bll я должен получить для этого, я добавил интерфейсы IBaseBLL для возвращаемого типа моей функции

Моя функция:

public static IBaseBLL<T> GetProperBllFromObjName<T>(string entityName) 
    { 
     IBaseBLL<T> baseBLL = null; 
     switch (entityName) 
     { 
      case "Country": 
       CountryBLL<Country> aa = new CountryBLL<Country>(); 
       baseBLL = (IBaseBLL<T>) aa; //error line 
       break; 
     } 


     return baseBLL; 
    } 

, когда я вызываю функцию так:

IBaseBLL<BaseEntity> mainBll = GetProperBllFromObjName("Country"); 

Но я не могу бросить исключение в строке, где я добавил комментарий «линия ошибки»

так, что я должен делать в этом случае , Единственное, что я хочу, это написать функцию, чтобы решить, какой bll мне следует использовать. (я не хочу менять bll declerations).

+0

@FyodorX: Это вопрос C#, а не вопрос Java. –

+0

@JeffreyBosboom Я изменил тег на C#; хороший звонок –

+0

@JeffreyBosboom: Ой! Извините, я должен попробовать спать время от времени. – FyodorX

ответ

1

Если добавить out к определению IBaseBLL<T> как это: <out T> это вероятно, будет работать (не может увидеть остальную часть кода, чтобы убедиться, что это не что-то другое), если у вас есть методы, которые имеют IBaseBLL<T>T как входной параметр - это наверняка сломает его (поскольку он даже не будет компилироваться).

следующие работы, но если вы берете на out ключевое слово, вы получите исключение:

namespace MyProgram 
{ 
    public class BaseEntity {}  
    public class CountryDLL<TEntity> {}  
    public class MainObjDLL<TEntity> {}  
    public interface IBaseBLL<out TEntity> {}  
    public class MainObj: BaseEntity {}  
    public class Country : MainObj {}  
    public class CountryBLL<TEntity> : CountryDLL<TEntity>,IBaseBLL<TEntity> where TEntity : Country {}  
    public class MainObjBLL<TEntity> : MainObjDLL<TEntity>, IBaseBLL<TEntity> where TEntity : MainObj {}  

    class Program 
    {  
     public static IBaseBLL<T> GetProperBllFromObjName<T>(string entityName) 
     { 
      IBaseBLL<T> baseBLL = null; 
      switch (entityName) 
      { 
       case "Country": 
        CountryBLL<Country> aa = new CountryBLL<Country>(); 
        baseBLL = (IBaseBLL<T>) aa; //error line 
        break; 
      } 

      return baseBLL; 
     } 

     static void Main() 
     { 
      IBaseBLL<Country> c = GetProperBllFromObjName<Country>("Country"); 
      IBaseBLL<BaseEntity> d = GetProperBllFromObjName<BaseEntity>("Country"); 
     } 
    } 
} 

Использование out и его партнер, in, называется contravariance and covariance в C#.

В Интернете есть много других материалов. Я бы предложил прочитать об этом.

Одна вещь, которую я не читал, я знаю, как запомнить разницу - это довольно легко imho. Если все ваши методы вернутся T, то вы можете добавить out (подумайте о коллекции и возвращаемых предметах в коллекции - они приходят из из коллекции). Если все ваши методы принимают T, то вы можете добавить in (еще раз, коллекцию - вы можете добавить вещи, и они идут в сборник). Однако, если у вас есть методы, которые делают оба, вы не можете добавить ни одно ключевое слово в параметр общего типа. Также, как только вы выберете ключевое слово и код против него или отпустите его, вы сосете; вы всегда можете добавить его позже и быть в порядке, но как только вы выбрали тот, вы застряли с ним.

+0

что делать, если я хочу вызвать функцию d.Select(). есть функция select в классе MainObjDLL, но в IBaseBLL нет функции выбора, и я не могу добавить функцию выбора, так как она хочет удалить «выход». Чтобы вызвать этот метод, есть ли какой-либо способ, кроме отражения? – brtb

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

  • Нет связанных вопросов^_^