泛型类型和继承混淆
本文关键字:继承 泛型类型 | 更新日期: 2023-09-27 18:21:46
我有一个类层次结构,如下所示:
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。(我不想改变所有的决定)。
如果像这样将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#中被称为逆方差和协方差。
网上还有很多其他材料。我建议你读一下。
有一件事我没有读过,我知道如何记住区别——这很容易。如果您的所有方法都返回T
,那么您可以添加out
(想想一个集合和返回集合中的项——它们从集合的中出来)。如果你的所有方法都接受T
,那么你就可以添加in
(同样,集合-你可以添加东西,它们会进入集合中的)。但是,如果您有同时执行这两种操作的方法,则不能将任一关键字添加到泛型类型参数中。同样,一旦你选择了一个关键词并对其进行编码或发布它,你就很糟糕;你总是可以稍后添加它,但一旦你选择了一个,你就会被它卡住。