您是否认为创建一个抽象泛型类是一种可接受或不好的做法,该类将类型参数作为一个派生自己的类?
这允许抽象泛型类操作派生类的实例,特别是在必要时创建派生类的new()实例的能力,并且可以帮助避免从派生类派生的具体类中重复代码 .
如果“糟糕”你更喜欢处理这种情况的替代方案,你将如何构建下面的代码?
例如:-
// We pass both the wrapped class and the wrapping class as type parameters
// to the generic class allowing it to create instances of either as necessary.
public abstract class CoolClass<T, U>
where U : CoolClass<T, U>, new()
{
public T Value { get; private set; }
protected CoolClass() { }
public CoolClass(T value) { Value = value; }
public static implicit operator CoolClass<T, U>(T val)
{
// since we know the derived type and that its new(), we can
// new up an instance of it (which we couldn't do as an abstract class)
return new U() { Value = val};
}
public static implicit operator T(CoolClass<T, U> obj)
{
return obj.Value;
}
}
还有第二个问题:为什么这些隐式算子中的一个有效,而另一个没有?
例如
public class CoolInt : CoolClass<int, CoolInt>
{
public CoolInt() { }
public CoolInt(int val) (val) { }
}
// Why does this not work
CoolInt x = 5;
// when this works
CoolInt x2 = (CoolInt)5;
// and this works
int j = x;
2 回答
这有点主观,但我不是隐性演员的忠实粉丝 . 当你使用代码时,代码经常会产生误导,有时如果是由implisit强制转换引起的,很难找到错误 . 如果你的课程只是为了使用而设计,那么我就不会这样使用它 .
因为您定义了
CoolClass<T, U>
的转换,而不是CoolInt
. 它们是不同的类型 . 如果你在CoolInt实现中有这个方法,它会工作:关于泛型的用法:
如果您需要使用许多类创建复杂的继承层次结构(例如,引入新的抽象级别可能会非常棘手),那么泛型的这种使用会给您的体系结构带来限制 . 但这真的取决于你需要什么 . 我实际上在其中一个项目中使用了这样的tecnique来避免代码重复 . 如果您的
CoolClass
克服new()限制,您也可以将委托Func<U>
传递给构造函数:)这是C中常见的(也是好的!)模式,看起来有点像这样:
我们将它用于静态多态/继承以及其他 .
但是,在.NET中,泛型参数在运行时并且还有反射,我不完全确定它的好处 . 我的意思是,使用派生类型是有用的,但你必须问自己 - 对于什么有用,它与直接继承有什么不同?