【问题标题】:How to access static methods of generic types如何访问泛型类型的静态方法
【发布时间】:2012-02-27 03:02:06
【问题描述】:
public class BusinessObjects<O>
    where O : BusinessObject
{
    void SomeMethod()
    {
        var s = O.MyStaticMethod(); // <- How to do this?
    }
}

public class BusinessObject
{
    public static string MyStaticMethod()
    {
        return "blah";
    }
}

是否有正确的面向对象的方法来实现这一点,还是我需要求助于反射?

编辑:我试图过度简化这个问题而忽略了一个重要点。 MyStaticMethod 使用反射并且需要派生类型来返回正确的结果。然而,我刚刚意识到我的设计中的另一个缺陷是我不能拥有静态虚拟方法,我认为这就是我所需要的。

看来我需要找到另一种方法来解决这个问题。

【问题讨论】:

  • 查看这里了解更多信息:stackoverflow.com/q/196661/114029
  • 我认为这是一个很好的问题。目前无法在 C# 中完成。但这对于 Microsoft 添加到 .Net 5+ 是有用的

标签: c# oop generics static


【解决方案1】:

不能像这样引用静态成员的原因:

O.MyStaticMethod(); 

是因为你不知道 O 是什么类型。是的,继承自BusinessObject,但类型之间不继承静态成员,所以只能从BusinessObject中引用MyStaticMethod。

【讨论】:

  • @DanielHilgarth,删除了错误的例子。尽管编译器允许您通过派生类调用静态方法,但静态成员仍然是不被继承的。生成的 IL 实际上将调用基类上的方法。同样,尽管编译器允许这样做,但从派生类型引用静态方法是不好的形式,可能会导致混淆,尤其是在使用创建模式时。
  • 当您说编译器会将Foo.MyStaticMethod() 更改为BusinessObject.MyStaticMethod() 时,您的评论是正确的。但是,这并不能使您的答案正确。这根本不正确,您只能引用(您的意思是“呼叫”吗?)MyStaticMethod 来自BusinessObject
  • O 是一个泛型类型参数。正如我们已经同意的那样,类型之间没有静态方法的继承,因此您不能期望能够在这种上下文中派生自 BusinessObject 的某个类型 O 上调用此方法。编译器团队本可以在这里提供一些魔法,就像他们在显式类型名称的情况下所做的那样,但[谢天谢地]他们没有。我同意我的回答并不像它可能的那样冗长,但我仍然不会说它不正确。
  • 我不同意静态方法没有继承。如果没有继承,Foo.MyStaticMethod() 确实是无效的。此外,如果您想在Foo 上提供MyStaticMethod 的不同实现,则必须使用new 修饰符,该修饰符用于显式隐藏从基类继承的成员。 new 修饰符的示例甚至包含一个带有静态成员的示例。
  • 静态方法唯一没有的就是动态调度,即多态性。我的猜测是 that 是执行 OP 尝试执行的操作是非法的实际原因,因为没有动态调度,这始终与使用泛型参数约束的类相同(@987654331 @ 在这个例子中)。
【解决方案2】:

如果你强制OBusinessObject继承,为什么不这样称呼它:

void SomeMethod()
{
    var s = BusinessObject.MyStaticMethod(); // <- How to do this?
}

【讨论】:

    【解决方案3】:

    您不能通过泛型类型参数访问静态方法,即使它被限制为一个类型。直接使用约束类即可

    var s = BusinessObject.MyStaticMethod();
    

    注意:如果您希望根据 O 的实例化类型调用静态方法,那么没有反射是不可能的。 .Net 中的泛型在编译时静态绑定到方法(与在实例化时绑定的 C++ 不同)。由于无法静态绑定到实例化类型上的静态方法,因此这是不可能的。虚拟方法有点不同,因为您可以静态绑定到虚拟方法,然后让动态调度在实例化类型上调用正确的方法。

    【讨论】:

    • 猜我没有提供足够的信息。立即检查更新的问题...
    • @BrandonMoore 更新了我的答案,以便更详细地了解限制
    • 是的,因为我不能有一个虚拟静态方法来扼杀我的方法。我认为反思将是要走的路。
    • 我想我本可以同样将其标记为答案,但由于我只能选择一个,所以我选择了一个在阅读时不会让我思考太多的那个:)
    • @BrandonMoore 绝对会选择您认为最能准确回答您的问题的那个:)
    猜你喜欢
    • 2011-08-19
    • 2020-05-07
    • 2010-11-24
    • 2014-07-06
    • 2010-10-16
    • 2012-02-10
    • 1970-01-01
    • 2017-12-29
    • 2010-10-30
    相关资源
    最近更新 更多