C# 通用基础多态性

标签 c# generics inheritance polymorphism

我有一个通用基类和两个从基类派生的类。我想用对象工厂创建这种派生类。但我不能用通用基类来做到这一点。我可以用 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/

相关文章:

c# - 嵌套的 xaml 元素 - 在代码中重写它

java - 在模棱两可的情况下应该使用哪个 Java 泛型?

java - instanceof 运算符 - 为什么会出现非法编译时错误

c# - c# System.Type 类型如何具有名称属性

c# - Newtonsoft如何读取多个json的内容?

c# - (400) 错误请求和更新条目时发生错误

c# - 使用泛型扩展接口(interface)不可分配给父级 c#

c# - 在基类的惰性方法中获取继承类名

java - 父类(super class)对子类对象的引用显示与子类对子类对象的引用相同的行为

c# - 使用 LINQ 在 C# 中计算文件数