Product包含一个静态方法MyMethod()。
我想从静态方法Widget.MyMethod()调用静态方法Product.MyMethod()。
我不能使用base关键字,因为它仅适用于实例方法。
我可以显式地调用Product.MyMethod(),但如果以后将Widget更改为派生自另一个类,则必须修改该方法。
在C#中是否有类似于base的语法,允许我从派生类的静态方法中调用基类的静态方法?
static
方法基本上是一种从面向对象概念中回退的方法。因此,在继承层次结构中它们不太灵活,不能直接做到这样。
我能够想到的最接近的东西是一个using
指令。
using mybaseclass = Namespace.BaseClass;
class MyClass : mybaseclass {
static void MyMethod() { mybaseclass.BaseStaticMethod(); }
}
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);
}
}
使用反射调用静态方法与调用实例方法完全相同,只需将实例参数传递为 null。由于该方法在祖先中定义,因此需要使用 FlattenHierarchy。
var type = assy.GetType("MyNamespace.MyType");
MethodInfo mi = type.GetMethod("MyStaticMethod",
BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy);
mi.Invoke(null, null);
public class Parent1
{
protected static void Foo()
{
Console.WriteLine("Parent1");
}
}
public class Child : Parent1
{
public static void Foo()
{
return Parent1.Foo();
}
}
这可以用于单元测试受保护的静态方法(例如)。
考虑到静态方法不应该依赖实例数据,所以您应该拥有一个基于参数或类似东西不同行为的静态“MyMethod”。
请记住,在一个类中定义的静态方法只是整理代码的一种方式……但如果该方法放在其他地方,它仍然是一样的,因为它不依赖于它所放置的对象。
编辑: 我认为您最好明确使用Product.MyMethod...... 如果您认为这样做...... 您的Widget更改其基类的可能性不大...... 在那种情况下,这只是一种较小的代码更改。
静态方法是“类级别”方法。它们旨在成为适用于特定类的所有实例的方法。因此,继承此方法没有意义,因为这会改变应用于类实例的含义。例如,如果您正在循环遍历产品集合(其中一些是Widget,一些不是),并在每个产品上调用MyMethod,则调用的方法将由类的实例确定。这违反了静态方法的目的。
您可能可以通过根本不使用静态方法来更清晰地完成您想要的操作,因为在您的示例中,似乎MyMethod并不适用于Product的所有实例。但是,您可以通过使用像“IMyMethod”这样的接口类来实现您所描述的相同效果。这种方法仍然没有使用静态方法。我想我没有看到需要使用静态方法的必要性。您为什么要使用静态方法呢?
非常简单。比使用别名、反射等要简单得多。也许在较新版本的.NET中,这个过程已经变得更加容易了,我不确定,但这样做完全没有问题。与实例方法一样,访问基本方法并不需要使用base
关键字,它是可选的,通常在继承和基类具有相同名称的方法时必须使用。即使没有base
关键字,您也可以像调用类中的方法一样访问基类的静态方法。我只测试了从派生类的< strong >static< /strong >方法调用基础< strong >static< /strong >方法的情况。如果从实例方法调用静态方法,则可能不起作用。
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();
}
}
from static method Widget.MyMethod()
,这恰好与基本方法的名称相同。这就是代码示例使事情更清晰的地方。我会使用他们的示例来解决问题。我会保留我的答案,因为这在谷歌上出现,并适用于调用基类静态方法的问题标题。 - AaronLS
Widget.MyMethod
。首先要考虑一下Widget.MyMethod
和Product.MyMethod
是否在做相同的事情,以便它们的名称相同。如果它们是等效的(对用户来说意思相似),那么你唯一的选择就是将它们变成非静态方法。虽然我认为这很有用,但 C# 没有静态成员继承的概念。现在想象一下FancyWidget
的孙子类,FancyWidget.MyMethod
应该调用什么?如果你认为应该调用Widget.MyMethod
,那么 C# 没有这样的东西(我认为任何面向对象编程语言都没有)。 - nawfal