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

时间:2013-10-29 13:57:28

标签: c# static polymorphism

我想从这样的事情开始:

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

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

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


这是一个简单的演示程序(此处不一定要进行空检查,只是演示如何检查属性是否实际存在。)请注意,提供通用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
    {
    }
}