【问题标题】:What's different between generic and polymorphism in C# method's arguments? [closed]C# 方法的参数中的泛型和多态性有什么不同? [关闭]
【发布时间】:2020-12-25 02:01:54
【问题描述】:

我有一个类需要使用一个对象,而该对象是某种类的约束。 但是,我有两个设计来实现这个方法:泛型和多态,然后是下面的示例代码:

class S3 : S{}
class S2 : S{}
class S{}

class C : A{
    public override void DoOne(S s){
        var tmp = s as S3;
    }
    public override void DoTwo<T>(T s){
        var tmp = s as S3;
    }
}
class B : A{
    public override void DoOne(S s){
        var tmp = s as S2;
    }
    public override void DoTwo<T>(T s){
        var tmp = s as S2;
    }
}
abstract class A{
    public abstract void DoOne(S s);
    public abstract void DoTwo<T>(T s) where T : S;
}

var s2 = new S2();
var b = new B();
b.DoOne(s2);
b.DoTwo(s2);

B 类需要使用S2 对象,也许我有C 类需要使用S3 对象。 我不知道实施这些更好。

【问题讨论】:

  • 方法不止这些,何必止步于此?简而言之,您的两种变体都是可疑,此外,您应该始终更喜欢组合而不是继承。但是,该问题缺乏足够的约束或用例来使任何答案有用。也就是说,这段代码无论哪种方式都很好(它可以工作),但是当您尝试在某些情况下使用任何此类解决方案时,您可能会遇到一些问题和限制。
  • 事实上,我想比较那些性能或其他考虑因素。

标签: c# oop generics polymorphism


【解决方案1】:

这两种方式都不是类型安全的。两者都不会阻止您将S3 传递给BS2 传递给C。当您只使用一次T 作为参数类型时,泛型的使用是相当多余的。

更安全的方法是使用通用接口/抽象类A

abstract class A<T> where T : S {
    public abstract void DoOne(T s);
}

class C : A<S3> {
    public override void DoOne(S3 s){
        // ...
    }
}
class B : A<S2> {
    public override void DoOne(S2 s){
        // ...
    }
}

这样,CB 没有共同的基类。如果您想要类型安全,那就应该是这样。

如果您不希望类型安全(不推荐),请改为接受 S。泛型在这里并没有增加太多。

【讨论】:

    猜你喜欢
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    相关资源
    最近更新 更多