以下是我面临的场景:
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>接口,因为我不知道具体的类型。
希望这篇文章是描述性的,对回答我的问题有足够的帮助。
发布于 2009-11-22 15:46:32
您要做的事情在.NET 4.0中是受支持的,但在3.5中不受支持。它被称为generic covariance。在此期间,您可以做的是创建一个名为ITableDataAccessLayer的非泛型接口(在使用T的地方使用类型Object ),并提供显式接口实现。这是.NET中许多泛型类型处理它的方式。
发布于 2009-11-23 01:06:42
实际上,你想要协方差。几分。
首先,理解为什么有时这必须是非法的。以IList为例。假设您有一个IList<Giraffe>,一个长颈鹿列表。你能把它转换成动物的列表吗?不,不安全。是的,长颈鹿的名单是一份动物名单,从这个意义上说,名单上的所有东西都是动物。但是列表是可变的;您可以将一只老虎放入一个动物列表中,但是如果它真的是一个长颈鹿列表,那么这个方法就必须失败。由于这是不安全的,我们不会在C# 4中使IList协变。
其次,如果您对这个主题感兴趣,您可能想要阅读我的一长串博客文章,这些文章是关于如何设计该功能来维护类型安全的。
http://blogs.msdn.com/ericlippert/archive/tags/Covariance+and+Contravariance/default.aspx
第三,仅供参考,我将在接下来的几周内在我的博客上发布我们用来计算接口何时可以安全地协变或逆变的确切规则。
发布于 2009-11-22 15:45:16
这个可以编译吗?
UserDataAccessLayer udal = new UserDataAccessLayer();
ITableDataAccessLayer<TTableRecord> itdal = (ITableDataAccessLayer<TTableRecord>)udal;或者甚至只是
ITableDataAccessLayer<TTableRecord> itdal = new UserDataAccessLayer(); 由于它是一个通用接口,它可能需要知道它是什么类型?
知道错误消息也会很有帮助。这通常会让我们对这个问题有所了解。
https://stackoverflow.com/questions/1778030
复制相似问题