C# 将混凝土类型浇注到嵌套的常规基础类型

C# 将混凝土类型浇注到嵌套的常规基础类型,c#,generics,c#-4.0,C#,Generics,C# 4.0,假设我有类似于以下内容的嵌套泛型数据类: public class BaseRecordList<TRecord, TUserInfo> where TRecord : BaseRecord<TUserInfo> where TUserInfo : BaseUserInfo { public virtual IList<TRecord> Records { get; set; } public virtual int Limit

假设我有类似于以下内容的嵌套泛型数据类:

public class BaseRecordList<TRecord, TUserInfo>
    where TRecord : BaseRecord<TUserInfo>
    where TUserInfo : BaseUserInfo
{
    public virtual IList<TRecord> Records { get; set; }
    public virtual int Limit { get; set; }
}

public class BaseRecord<TUserInfo>
    where TUserInfo : BaseUserInfo
{
    public virtual DateTime CreationTime { get; set; }
    public virtual TUserInfo UserInfo { get; set; }
}

public class BaseUserInfo
{
    public virtual string Name { get; set; }
    public virtual int Age { get; set; }
}
公共类BaseRecordList
哪里有TRecord:BaseRecord
其中TUserInfo:BaseUserInfo
{
公共虚拟IList记录{get;set;}
公共虚拟整数限制{get;set;}
}
公共类基本记录
其中TUserInfo:BaseUserInfo
{
公共虚拟日期时间CreationTime{get;set;}
公共虚拟TUserInfo用户信息{get;set;}
}
公共类BaseUserInfo
{
公共虚拟字符串名称{get;set;}
公共虚拟整数{get;set;}
}
有两个具体版本,如下所示:

// Project 1: Requires some extra properties
public class Project1RecordList : BaseRecordList<Project1Record, Project1UserInfo> {}

public class Project1Record : BaseRecord<Project1UserInfo>
{
    public Guid Version { get; set; }
}

public class Project1UserInfo : BaseUserInfo
{
    public string FavouriteFood { get; set; }
}
//项目1:需要一些额外的属性
公共类Project1记录列表:BaseRecordList{}
公共类项目1记录:BaseRecord
{
公共Guid版本{get;set;}
}
公共类项目1UserInfo:BaseUserInfo
{
公共字符串FavoriteFood{get;set;}
}

//项目2:某些属性需要用于JSON序列化的备用名称
公共类项目2记录列表:BaseRecordList
{
[JsonProperty(“所有记录”)]
公共重写IList记录{get;set;}
}
公共类Project2Record:BaseRecord{}
公共类Project2UserInfo:BaseUserInfo
{
[JsonProperty(“用户名”)]
公共重写字符串名称{get;set;}
}
我很高兴有两个存储库分别返回Project1RecordList和Project2RecordList,但在我的代码中,我发现自己需要能够在一个地方处理这两个。我认为,在这一点上,我需要能够将这两种类型视为

BaseRecordList<BaseRecord<BaseUserInfo>, BaseUserInfo>
BaseRecordList
因为这是满足一般约束所需的最低要求,但尝试强制转换或使用“as”会引发无法转换的错误


有没有办法做到这一点,或者有没有更明智的方法来处理这种情况,而不需要大量的代码重复?如果有什么不同的话,这是针对一个web应用程序的,并且已经有大量的数据类,其中许多使用这些嵌套泛型。

您所谈论的是所谓的协方差,MSDN在这里有一篇很好的文章:

首先,创建一个新接口:

interface IBaseRecord<out TUserInfo>
  where TUserInfo : BaseUserInfo
{
}
public class BaseRecord<TUserInfo> : IBaseRecord<TUserInfo>
    where TUserInfo : BaseUserInfo
{
    public virtual DateTime CreationTime { get; set; }
    public virtual TUserInfo UserInfo { get; set; }
}
接口IBaseRecord
其中TUserInfo:BaseUserInfo
{
}
让BaseRecord从新接口继承:

interface IBaseRecord<out TUserInfo>
  where TUserInfo : BaseUserInfo
{
}
public class BaseRecord<TUserInfo> : IBaseRecord<TUserInfo>
    where TUserInfo : BaseUserInfo
{
    public virtual DateTime CreationTime { get; set; }
    public virtual TUserInfo UserInfo { get; set; }
}
公共类基记录:IBaseRecord
其中TUserInfo:BaseUserInfo
{
公共虚拟日期时间CreationTime{get;set;}
公共虚拟TUserInfo用户信息{get;set;}
}
如果操作正确,则应编译:

IBaseRecord<BaseUserInfo> project1 = new Project1Record();
IBaseRecord<BaseUserInfo> project2 = new Project2Record();
IBaseRecord project1=newproject1record();
IBaseRecord project2=新项目2record();
要将其扩展到BaseRecordList,请创建iBaserRecordList:

interface IBaseRecordList<out TRecord, out TUserInfo>
  where TRecord : IBaseRecord<TUserInfo>
  where TUserInfo : BaseUserInfo
{
}
接口IBaserRecordList
哪里有TRecord:IBaseRecord
其中TUserInfo:BaseUserInfo
{
}
让BaseRecordList从中继承:

public class BaseRecordList<TRecord, TUserInfo> : IBaseRecordList<TRecord, TUserInfo>
public类BaseRecordList:IBaseRecordList
然后按如下方式使用:

IBaseRecordList<IBaseRecord<BaseUserInfo>, BaseUserInfo> project1 = new Project1RecordList();
IBaseRecordList<IBaseRecord<BaseUserInfo>, BaseUserInfo> project2 = new Project2RecordList();
ibaserecordlistproject1=newproject1recordlist();
IBaseRecordList project2=新的Project2RecordList();

设置完成后,只需向接口添加任何需要通用的属性或函数。

并执行类似于您试图通过让通用接口从非通用接口继承来完成的操作。然后,您可以在需要同时处理所有内容的情况下使用非泛型类。非常好,谢谢!我不知道这个有名字。对于偶然发现这一点的任何其他人来说,可能值得指出的是,接口中的任何属性都不能有setter,现在考虑它是有意义的。