如何在多个类之间共享静态方法

本文关键字:之间 共享 静态方法 | 更新日期: 2023-09-27 18:37:14

我想从这样的东西开始:

class A { ... }
class B { ... }
class C { ... }

其中 A、B 和 C 具有静态方法 MyName。

然后我可以做:

Console.WriteLine(A.MyName());
Console.WriteLine(B.MyName());
Console.WriteLine(C.MyName());

然后之后我应该能够做这样的事情。

foreach(var type in new[] { typeof(A), typeof(B), typeof(C)) {
    ??? Console.WriteLine(t.MyName());
}

我该怎么做?

我还希望能够执行以下操作(但这可能是不可能的):

??? x = new A();
Console.WriteLine(x.MyName());
x = new B();
Console.WriteLine(x.MyName());

如何在多个类之间共享静态方法

您在此处尝试执行的操作是将元数据与类型相关联,如果您知道该类型,则可以查询该类型。 执行此操作的标准做法是使用自定义属性。 可以通过类型安全的方式查询这些属性,并提取每个属性的相关信息。它们在如何指定其继承以及是否可以应用多个相同属性类型方面非常灵活。 它们还可以应用于类以外的其他内容,例如属性或字段,这些内容可能很方便。


这是一个简单的演示程序(这里不是绝对必要的空检查,而只是演示如何检查属性是否确实存在。 请注意,提供通用 GetCustomAttribute 的扩展方法仅在 .NET 4.5 中添加。 以前的版本将要求您使用非通用版本并将其强制转换为相应的属性类型。

class Program
{
    static void Main(string[] args)
    {
        var types = new[] {typeof(A), typeof(B), typeof(C)};
        foreach (var type in types)
        {
            var attribute = type.GetCustomAttribute<NameAttribute>();
            if (attribute != null)
                Console.WriteLine(attribute.Name);
        }
        Console.ReadLine();
    }
    public sealed class NameAttribute : Attribute
    {
        public string Name { get; private set; }
        public NameAttribute(string name)
        {
            Name = name;
        }
    }
    [Name("A Name")]
    public class A
    {
    }
    [Name("B Name")]
    public class B
    {
    }
    [Name("C Name")]
    public class C
    {
    }
}

为了在类之间共享一些静态成员,您需要从包含静态成员的基类继承:

public class Base
{
    public static string MyName() { return "Bob"; }
}
public class A : Base
{        
}
public class B : Base
{
}

您无法在 foreach 循环中执行正在尝试的操作,因为变量 t 具有类型 Type,而Type没有任何MyName属性。您应该使用反射来获取MyName值:

Console.WriteLine(A.MyName()); // Bob
Console.WriteLine(B.MyName()); // Bob
foreach(var type in new[] { typeof(A), typeof(B) })
{
    var flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy;
    var method = type.GetMethod("MyName", flags);
    Console.WriteLine(method.Invoke(null, null));
}

此代码打印这两种类型的Bob