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
{
}

t変数には型がTypeあり、プロパティTypeがないため、 foreach ループで試していることはできません。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 に答える