简体   繁体   English

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

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

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的语法允许我从派生类的静态方法中调用基类的静态方法吗?

static methods are basically a method to fallback from object oriented concepts. static方法基本上是从面向对象的概念中回退的方法。 As a consequence, they are not very flexible in inheritance hierarchies and it's not possible to do such a thing directly. 因此,它们在继承层次结构方面不是很灵活,并且不可能直接执行这样的操作。

The closest thing I can think of is a using directive. 我能想到的最接近的是using指令。

using mybaseclass = Namespace.BaseClass;

class MyClass : mybaseclass {

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

}

Calling a static method using reflection is exactly the same as calling an instance method except that you pass null for the instance. 使用反射调用静态方法与调用实例方法完全相同,只是为实例传递null。 You need FlattenHierarchy because it's defined in an ancestor. 你需要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? 您是否正在尝试进行函数式编程,如果是这样,为什么不使用lambda表达式呢? If you want polymophic behaviours with shared state, instance methods would be better. 如果您希望多态行为具有共享状态,则实例方法会更好。

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);
    }
}

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). 可用于单元测试受保护的静态方法(例如)。

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. 继承应该用于建立“is-a”关系,而不仅仅是促进代码重用。 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. 我想你可以在子类型和它的父类之间引入一个中间类型,但我会让这种可能性驱动我的设计。

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. 实现Factory模式的一种方法是通过Factory Methods,一个构造该类实例的类的静态方法。 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. 更好的实现可能使用相同的技术,但将Factory方法移动到Factory类并使用构造函数逻辑(内部现在,而不是私有),可能与初始化方法结合使用,以创建对象。 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. 如果您继承的行为是来自类的外部(decryption / validation / etc),则可以使用Factory中的共享方法(或组合)来允许在Factory方法之间重用。

Without knowing the goal of your use of static methods it's difficult to give you an exact direction, but hopefully this will help. 在不知道使用静态方法的目标的情况下,很难给出确切的方向,但希望这会有所帮助。

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: 一些建议:

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. 比使用别名,反射等简单得多。也许在新增的.NET,IDK中它变得更容易,但这种方法非常好。 Just like with instance methods, accessing base methods doesn't require base be used, it is optional, usually necessary when the inheriting and base class have a method of the same name. 与实例方法一样,访问基本方法不需要使用base ,它是可选的,通常在继承和基类具有相同名称的方法时是必需的。 Even without the base keyword, you can access the static methods of a base class as if they were in the class you are calling from. 即使没有base关键字,您也可以访问基类的静态方法,就像它们在您调用的类中一样。 I only tested this when calling a base static method from a derived class's static method. 我只在从派生类的静态方法调用基本静态方法时测试了这个。 Might not work if you are calling from an instance method to a static method. 如果从实例方法调用静态方法,则可能无法工作。

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();            
    }
}

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可能不会改变它的基础...而且在这种情况下它是一个小的改变在代码中。

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. 例如,如果您循环遍历产品集合(某些Widget,某些不是)并在每个产品上调用MyMethod,则调用的方法将由类的实例确定。 This violates the purpose of static methods. 这违反了静态方法的目的。

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. 你可以通过简单地完全不使用静态方法来做你想要更干净的事情,因为在你的例子中,似乎MyMethod并不适用于所有的Product实例。 However, you can achieve the same affect you are describing by using an interface class like 'IMyMethod'. 但是,您可以使用像“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? 为什么要使用静态方法开始?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从基类调用派生类方法? - How do I call a derived class method from the base class? 如何从 C# 中的派生类实例调用基方法? - How to call base method from derived class instance in C#? 我可以调用基于 class 的 static 方法,并参考实现该基础 ZA2F2ED4F8EBC2CBB4C21 的 class 吗? - Can I call a static method that lives on a base class with a reference the the class implementing that base class (in C#)? C#:从基类静态方法确定派生对象类型 - C#: Determine derived object type from a base class static method 如何使用 C# 反射调用静态泛型类的静态方法? - How to call static method of static generic class with C# Reflection? C#如何在不使方法静态的情况下从界面内的另一个类调用方法? - C# How do I call a method from another class inside of my interface without making the method static? 从base的类静态方法获取派生类类型 - Get derived class type from a base's class static method 如何从 C# 中的基础 class 参考中调用派生 class 的通用方法 - How to call generic method of derived class from base class reference in C# 如何从其他类的静态方法中调用非静态方法? - How do I call a non-static method from a static method from a different class? 如何在C#中使用静态工厂方法创建基类? - How to create a base class with static factory method in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM