C#:如何从派生类的静态方法调用基类的静态方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/603177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 09:57:32  来源:igfitidea点击:

C#: How do I call a static method of a base class from a static method of a derived class?

c#inheritancestaticbasederived-class

提问by MindModel

In C#, I have base class Product and derived class Widget.

在 C# 中,我有基类 Product 和派生类 Widget。

Product contains a static method MyMethod().

产品包含一个静态方法 MyMethod()。

I want to call static method Product.MyMethod() from static method Widget.MyMethod().

我想从静态方法 Widget.MyMethod() 调用静态方法 Product.MyMethod()。

I can't use the base keyword, because that only works with instance methods.

我不能使用 base 关键字,因为它只适用于实例方法。

I can call Product.MyMethod() explicitly, but if I later change Widget to derive from another class, I have to revise the method.

我可以显式调用 Product.MyMethod(),但是如果我以后将 Widget 更改为从另一个类派生,则必须修改该方法。

Is there some syntax in C# similar to base that allows me to call a static method from a base class from a static method of a derived class?

C# 中是否有一些类似于 base 的语法,允许我从派生类的静态方法调用基类中的静态方法?

回答by Mehrdad Afshari

staticmethods are basically a method to fallback from object oriented concepts. As a consequence, they are not very flexible in inheritance hierarchies and it's not possible to do such a thing directly.

static方法基本上是一种从面向对象概念回退的方法。因此,它们在继承层次结构中不是很灵活,并且不可能直接做这样的事情。

The closest thing I can think of is a usingdirective.

我能想到的最接近的是using指令。

using mybaseclass = Namespace.BaseClass;

class MyClass : mybaseclass {

  static void MyMethod() {  mybaseclass.BaseStaticMethod();  }

}

回答by Romias

Having into account that a Static method shoudn't relay in instance data... you should have a static "MyMethod" that behaves diferent based on a parameter or something like that.

考虑到静态方法不应该在实例数据中中继......你应该有一个静态的“MyMethod”,它根据参数或类似的东西表现不同。

Remember that the static method defined in one class is just a way to order your code... but it is the same if that method is placed elsewhere... because it don't relay on the object where it is placed.

请记住,在一个类中定义的静态方法只是对代码进行排序的一种方式……但是如果将该方法放置在其他地方,则情况相同……因为它不会在放置它的对象上进行中继。

EDIT:I think your best choise is to use Product.MyMethod explicitly... If you think it... it should't be probable that your Widget change its base clase... and also in that case it is a minor change in code.

编辑:我认为你最好的选择是明确使用 Product.MyMethod ......如果你认为......你的 Widget 不太可能改变它的基类......而且在这种情况下它是一个小变化在代码中。

回答by Michael Meadows

Static methods are not polymorphic, so what you want to do is impossible.

静态方法不是多态的,所以你想做的事情是不可能的。

Trying to find a way to treat static methods as polymorphic is possible but dangerous, because the language itself doesn't support it.

试图找到一种将静态方法视为多态的方法是可能的,但很危险,因为语言本身不支持它。

Some suggestions:

一些建议:

回答by marcumka

It can be done, but I don't recommend it.

可以这样做,但我不建议这样做。

public class Parent1
{
    public static void Foo()
    {
        Console.WriteLine("Parent1");
    }
}

public class Child : Parent1
{
    public new static void Foo()
    {
        Type parent = typeof(Child).BaseType;
        MethodInfo[] methods = parent.GetMethods();
        MethodInfo foo = methods.First(m => m.Name == "Foo");
        foo.Invoke(null, null);
    }
}

回答by Dunk

Static methods are "Class-Level" methods. They are intended to be methods that apply to all instances of a specific class. Thus, inheritance of this method does not make sense as it would change the meaning to apply to instances of the class. For instance, if you were looping through a collection of Products (some of Widget, some not) and called MyMethod on each Product then the method that was called would be determined by the instance of the class. This violates the purpose of static methods.

静态方法是“类级”方法。它们旨在成为适用于特定类的所有实例的方法。因此,此方法的继承没有意义,因为它会改变应用于类实例的含义。例如,如果您在循环产品集合(有些是 Widget,有些不是)并在每个产品上调用 MyMethod,那么调用的方法将由类的实例确定。这违反了静态方法的目的。

You can probably do something like you want more cleanly by simply not using static methods at all, because in your example it does not seem like MyMethod applies to all instances of Product. However, you can achieve the same affect you are describing by using an interface class like ‘IMyMethod'. This approach is still not using a static method. I guess I'm not seeing a need for a static method. Why do you want to use a static method to begin with?

您可能可以通过根本不使用静态方法来做更干净的事情,因为在您的示例中,MyMethod 似乎并不适用于 Product 的所有实例。但是,您可以通过使用像“IMyMethod”这样的接口类来实现您所描述的相同效果。这种方法仍然没有使用静态方法。我想我不需要静态方法。为什么要使用静态方法开始?

回答by Peter Wone

Calling a static method using reflection is exactly the same as calling an instance method except that you pass null for the instance. You need FlattenHierarchy because it's defined in an ancestor.

使用反射调用静态方法与调用实例方法完全相同,只是您为实例传递 null。您需要 FlattenHierarchy,因为它是在祖先中定义的。

var type = assy.GetType("MyNamespace.MyType");
MethodInfo mi = type.GetMethod("MyStaticMethod", 
  BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
mi.Invoke(null, null);

Further reading and thinking leaves me asking the same questions as others who have responded: why use static methods like this? Are you trying to do functional programming, and if so why not use lambda expressions instead? If you want polymophic behaviours with shared state, instance methods would be better.

进一步阅读和思考让我提出了与其他回答相同的问题:为什么要使用这样的静态方法?您是否正在尝试进行函数式编程,如果是,为什么不改用 lambda 表达式?如果您想要具有共享状态的多态行为,实例方法会更好。

回答by AaronLS

It's very simple. Much simpler than using aliasing, reflections, etc. Maybe it's been made easier in newer additions of .NET, IDK, but this works perfectly fine. Just like with instance methods, accessing base methods doesn't require basebe used, it is optional, usually necessary when the inheriting and base class have a method of the same name. Even without the basekeyword, you can access the static methods of a base class as if they were in the class you are calling from. I only tested this when calling a base staticmethod from a derived class's staticmethod. Might not work if you are calling from an instancemethod to a static method.

这很简单。比使用别名、反射等简单得多。也许在 .NET、IDK 的新添加中它变得更容易了,但这工作得非常好。与实例方法一样,访问基方法不需要base使用,它是可选的,通常在继承和基类具有相同名称的方法时是必需的。即使没有base关键字,您也可以访问基类的静态方法,就像它们在您正在调用的类中一样。我只在从派生类的静态方法调用基本静态方法时对此进行了测试。如果您从实例方法调用静态方法,则可能不起作用。

public class BaseThings
{
    protected static void AssertPermissions()
    {
        //something
    }
}

public class Person:BaseThings
{
    public static void ValidatePerson(Person person)
    {
        //just call the base static method as if it were in this class.
        AssertPermissions();            
    }
}

回答by tvanfosson

First and foremost, if you're worried about re-parenting a class, then you're probably doing inheritance wrong. Inheritance should be used to establish "is-a" relationships, not simply foster code reuse. If you need code re-use alone, consider using delegation, rather than inheritance. I suppose you could introduce an intermediate type between a sub-type and its parent, but I would let that possibility drive my design.

首先也是最重要的,如果你担心重新培养一个类,那么你很可能在继承上做错了。继承应该用于建立“is-a”关系,而不是简单地促进代码重用。如果您需要单独重用代码,请考虑使用委托,而不是继承。我想你可以在子类型和它的父类型之间引入一个中间类型,但我会让这种可能性驱动我的设计。

Second, if you need to use functionality from the base class but extend it AND the use case calls for a static method, then you might want to consider using some external class to hold the functionality. The classic case for this in my mind is the Factory pattern. One way to implement the Factory pattern is through Factory Methods, a static method on a class that constructs an instance of that class. Usually the constructor is protected so that the factory method is the only way to build the class from outside.

其次,如果您需要使用基类中的功能但扩展它并且用例调用静态方法,那么您可能需要考虑使用一些外部类来保存功能。在我看来,这方面的经典案例是工厂模式。实现工厂模式的一种方法是通过工厂方法,这是一个类上的静态方法,用于构造该类的实例。通常构造函数是受保护的,因此工厂方法是从外部构建类的唯一方法。

One way to approach re-use with Factory Methods in an inheritance hierarchy would be to put the common code in a protected method and call that method from the Factory Method rather than directly call the base class Factory Method from a sub-types Factory Method. A better implementation might use the same technique but move the Factory Methods to a Factory class and use the constructor logic (internal now, not private), perhaps in conjunction with an initialization method(s), to create the object. If the behavior you are inheriting is external from the class (decryption/validation/etc), you can use shared methods (or composition) within the Factory to allow re-use between the Factory methods.

在继承层次结构中使用工厂方法进行重用的一种方法是将公共代码放在受保护的方法中并从工厂方法调用该方法,而不是从子类型工厂方法直接调用基类工厂方法。更好的实现可能使用相同的技术,但将工厂方法移动到工厂类并使用构造函数逻辑(现在是内部的,不是私有的),也许结合初始化方法来创建对象。如果您继承的行为是类的外部行为(解密/验证等),您可以在工厂内使用共享方法(或组合)以允许在工厂方法之间重用。

Without knowing the goal of your use of static methods it's difficult to give you an exact direction, but hopefully this will help.

在不知道您使用静态方法的目标的情况下,很难给您一个确切的方向,但希望这会有所帮助。

回答by mlipman

It can be done:

可以办到:

public class Parent1
{
    protected static void Foo()
    {
        Console.WriteLine("Parent1");
    }
}

public class Child : Parent1
{
    public static void Foo()
    {
        return Parent1.Foo();
    }
}

Can be useful for unit testing protected static methods (for example).

可用于单元测试受保护的静态方法(例如)。