我有一个类层次结构,如下所示:
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");
但我无法在我添加评论&#34;错误行&#34;
的情况下排除异常所以在这种情况下该怎么做。我唯一想要的是编写一个函数来决定我应该使用哪个bll。 (我不想改变bll declerations)。
答案 0 :(得分: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
在C#中称为contravariance and covariance。
网上有很多其他资料。我建议阅读它。
有一件事,我没有读过,我知道的是如何记住差异 - 这很容易。如果您的所有方法都返回T
,那么您可以添加out
(想想集合并返回集合中的项目 - 它们来自 out 集合)。如果您的所有方法都接受T
,那么您可以添加in
(再次,收集 - 您可以添加内容,然后在集合中)。但是,如果您有两种方法,则无法将任何关键字添加到泛型类型参数。一旦你选择一个关键字和代码反对它或释放它你就是吮吸;你可以随时添加它,并且没关系,但是一旦你选择了它,你就会坚持下去。