2016-03-23 5 views
-1

静的メソッドの動作は、呼び出されたクラスに依存して行うことができますか? など。私はBase.GetClassNameMethodBase.GetCurrentMethod().DeclaringType.Nameを使用する場合は、 "ベース" が返されること静的メソッドは子クラスに依存しますか?

abstract class Base 
{ 
    public static string GetClassName() 
    { ???? } 
} 
class A : Base { } 
class B : Base { } 

static void Main(string[] args) 
{ 
    Console.WriteLine(A.GetClassName()); // Want to print "A" 
    Console.WriteLine(B.GetClassName()); // Want to print "B" 
} 

は注意してください。

はまた、これは以下のようないくつかの他のSOの質問に似ていることに注意してください、私は「あなたはできない」以外の回答を文書化するために、より簡潔な方法でそれを求めている:

+1

[C#仮想(または抽象)静的メソッド]の可能な複製(http://stackoverflow.com/questions/763344/c-sharp-virtual-or-abstract-static-methods) –

+0

@JasonWatkins。 dupとしてマークしてくれてありがとう。 http://meta.stackoverflow.com/questions/314210/should-i-ask-a-new-question-in-order-to-make-the-answer-easier-to-find私はそれをしていたはずです –

答えて

0

キーは、型パラメータを追加することです:

abstract class Base<T> 
    where T : Base<T> 
{ 
    public static string GetClassName() 
    { 
     return typeof(T).Name; 
    } 
} 

class A : Base<A> { } 

class B : Base<B> { } 

これはBaseの静的メンバがTが何であれ、特定のクラスBase<T>に属します。したがって、単一のBase.GetClassNameメソッドはもう存在しませんが、この場合は2つのメソッドがあります:Base<A>.GetClassNameBase<B>.GetClassNameです。さらに、型パラメーターの制約により、class B : Base<A>を持つことができなくなり、A.GetClassNameB.GetClassNameが異なるものを返すことが保証されます。子クラスに固有

動作がさらに拡張することができる。この場合

abstract class Base<T> 
where T : Base<T> 
{ 
    private static HashSet<string> values = new HashSet<string>(); 

    internal Base(string value) 
    { 
     if (Base<T>.values.Contains(value)) 
      throw new Exception("Not unique"); 
     else 
      Base<T>.values.Add(value); 
    } 

    public static string GetClassName() 
    { 
     return typeof(T).Name; 
    } 

    public static IEnumerable<string> GetValues() 
    { 
     return new LinkedList<string>(Base<T>.values); 
    } 
} 

class A : Base<A> 
{ 
    public A(string value) : base(value) { } 
} 

class B : Base<B> 
{ 
    public B(string value) : base(value) { } 
} 

static void Main(string[] args) 
{ 
    var a1 = new A("value"); 
    var a2 = new A("value 2"); 
    // var a3 = new A("value"); // Would throw an exception 
    var b = new B("value"); // Does not throw an exception 

    Console.WriteLine(A.GetClassName()); // Prints "A" 
    Console.WriteLine(B.GetClassName()); // Prints "B" 

    Console.WriteLine("The values in A:"); 
    foreach (var value in A.GetValues()) // This loop prints "value" and "value 2" 
    { 
     Console.WriteLine("\t" + value); 
    } 
    Console.WriteLine("The values in B:"); 
    foreach (var value in B.GetValues()) // This loop prints "value" 
    { 
     Console.WriteLine("\t" + value); 
    } 
} 

、異なる静的valuesオブジェクトがBase<A>/A及びBase<B>/Bです。

しかし、これにはすべて費用がかかります。上記の例では、Baseの子クラスは、すべての子クラスが事前にを知っていることなく、同じ静的オブジェクトにアクセスすることは不可能です。例えば。 BAと同じvaluesオブジェクトにアクセスできません。考えられる回避策の1つは、すべての子クラスで値を共有する場合にBase<agreed-upon-type>.valuesを使用することです。