我有一个通用基类和两个从基类派生的类。我想用对象工厂创建这种派生类。但我不能用通用基类来做到这一点。我可以用 Java 这样做,没有任何问题。我还在 C# 中通过装箱和拆箱解决了这个问题。执行此操作的正确方法是什么?
public abstract class Base<T> {
public abstract T Value {
get;
set;
}
}
public class Derived1 : Base<int> {
int value;
public override int Value {
get {
return value;
}
set {
this.value = value;
}
}
}
public class Derived2 : Base<float> {
float value;
public override float Value {
get {
return value;
}
set {
this.value = value;
}
}
}
public class Factory {
public Base create(int type) {
switch(type) {
case 1:
return new Derived1();
case 2:
return new Derived2();
}
}
}
谢谢!
已解决:我明白,由于任何接口(interface)都没有通用方法,因此它们也无济于事。唯一的解决方案是将值装箱到一个对象中。这是我的解决方案。
public abstract class Base {
public abstract object Value {
get;
set;
}
}
public class Derived1 : Base {
int value;
public override object Value {
get {
return value;
}
set {
this.value = (int) value;
}
}
}
public class Derived2 : Base {
float value;
public override object Value {
get {
return value;
}
set {
this.value = (float) value;
}
}
}
public class Factory {
public Base create(int type) {
switch(type) {
case 1:
return new Derived1();
case 2:
return new Derived2();
default:
return null;
}
}
}
现在我可以将所有派生对象视为基础对象。
最佳答案
您必须有一个非通用 Base<T>
返回类型;
您可以考虑使用 TypeCode
:
public class Factory {
public Base<T> create<T>() {
var typeCode = Type.GetTypeCode(typeof(T));
switch (typeCode)
{
case TypeCode.Empty:
break;
case TypeCode.Object:
break;
case TypeCode.DBNull:
break;
case TypeCode.Boolean:
break;
case TypeCode.Char:
break;
case TypeCode.SByte:
break;
case TypeCode.Byte:
break;
case TypeCode.Int16:
break;
case TypeCode.UInt16:
break;
case TypeCode.Int32: // Derived1 : Base<int>
return new Derived1();
break;
case TypeCode.UInt32:
break;
case TypeCode.Int64:
break;
case TypeCode.UInt64:
break;
case TypeCode.Single: // Derived2 : Base<float>
return new Derived2();
break;
case TypeCode.Double:
break;
case TypeCode.Decimal:
break;
case TypeCode.DateTime:
break;
case TypeCode.String:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
...此外,如果您使用界面,您可以“隐藏”<TypeParam>
从返回:
public interface IBase {
// properties/methods
}
然后:
public abstract class Base<T> : IBase {
// properties/methods
}
然后:
public class Factory {
public IBase create<T>() {
// logic
}
}
现在,返回Value
有三种选择:(1) 坚持不使用接口(interface)的实现IBase
; (2)使用dynamic
接口(interface)中的返回类型,或者; (3) 框 object
中的值正如你所做的那样。
注意:写下我的头顶,未经测试。
// 1. implementation without the interface
public abstract class Base<T> {
public abstract T Value {get; set;}
}
// 2. implementation with IBase
public interface IBase {
public dynamic Value {get; set;}
}
public abstract Base<T> : IBase {
public abstract dynamic Value {get; set;}
}
关于C# 通用基础多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41388605/