[英]Cast concrete class to generic base interface
这是我面临的情景:
public abstract class Record { }
public abstract class TableRecord : Record { }
public abstract class LookupTableRecord : TableRecord { }
public sealed class UserRecord : LookupTableRecord { }
public abstract class DataAccessLayer<TRecord> : IDataAccessLayer<TRecord>
where TRecord : Record, new() { }
public abstract class TableDataAccessLayer<TTableRecord> : DataAccessLayer<TTableRecord>, ITableDataAccessLayer<TTableRecord>
where TTableRecord : TableRecord, new() { }
public abstract class LookupTableDataAccessLayer<TLookupTableRecord> : TableDataAccessLayer<TLookupTableRecord>, ILookupTableDataAccessLayer<TLookupTableRecord>
where TLookupTableRecord : LookupTableRecord, new() { }
public sealed class UserDataAccessLayer : LookupTableDataAccessLayer<UserRecord> { }
public interface IDataAccessLayer<TRecord>
where TRecord : Record { }
public interface ITableDataAccessLayer<TTableRecord> : IDataAccessLayer<TTableRecord>
where TTableRecord : TableRecord { }
public interface ILookupTableDataAccessLayer<TLookupTableRecord> : ITableDataAccessLayer<TLookupTableRecord>
where TLookupTableRecord : LookupTableRecord { }
现在,当我尝试执行以下演员时,它不会编译:
UserDataAccessLayer udal = new UserDataAccessLayer();
ITableDataAccessLayer<TableRecord> itdal = (ITableDataAccessLayer<TableRecord>)udal;
但是,当我执行以下转换时,它编译时没有运行时错误:
UserDataAccessLayer udal = new UserDataAccessLayer();
ITableDataAccessLayer<UserRecord> itdal = (ITableDataAccessLayer<UserRecord>)udal;
我真的需要使用基础ITableDataAccessLayer<TableRecord>
接口,因为我不知道具体类型。
希望这个描述性和帮助足以回答我的问题。
您尝试执行的操作在.NET 4.0中受支持,但不支持3.5。 它被称为通用协方差 。 在此期间您可以做的是创建一个名为ITableDataAccessLayer的非泛型接口(使用类型Object,无论您使用何时使用T)并提供显式接口实现。 这是.NET中有多少泛型类型处理它。
的确,你想要协方差。 情侣点。
首先,要理解为什么有时这必须是非法的。 以IList为例。 假设你有一个IList<Giraffe>
,一个长颈鹿列表。 你能把它转换成动物名单吗? 不,不安全。 是的,长颈鹿列表是动物列表,因为列表中的所有内容都是动物。 但是名单是可变的; 你可以将一只老虎放入动物名单中,但如果它真的是长颈鹿的名单,那么这必须失败。 由于这不安全,我们不会在C#4中使IList协变。
其次,如果您对此主题感兴趣,您可能需要阅读我关于该功能如何设计以保持类型安全性的一系列博客文章。
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
第三,仅供参考我将在未来几周内发布我的博客上可以安全协变或逆变的界面时使用的确切规则。
这会编译吗?
UserDataAccessLayer udal = new UserDataAccessLayer();
ITableDataAccessLayer<TTableRecord> itdal = (ITableDataAccessLayer<TTableRecord>)udal;
甚至只是
ITableDataAccessLayer<TTableRecord> itdal = new UserDataAccessLayer();
因为它是一个通用接口,它可能需要知道它是什么类型的?
知道错误消息也会有所帮助。 这通常可以阐明这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.