0

我想从这样的事情开始:

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

2 回答 2

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两种类型。

于 2013-10-29T14:06:19.220 回答
1

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


这是一个简单的演示程序(此处的 null 检查不是绝对必要的,只是演示如何检查属性是否实际存在。)请注意,提供通用 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
    {
    }
}
于 2013-10-29T14:23:03.250 回答