关键是要增加一个类型参数:
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
静态成员属于特定类Base<T>
,无论T
是。所以不再有单一的方法,但是在这种情况下现在有两种方法:Base<A>.GetClassName
和Base<B>.GetClassName
。此外,对类型参数的约束使得不可能有class B : Base<A>
,这保证了A.GetClassName
和B.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);
}
}
在这种情况下,有在Base<A>
/A
和Base<B>
/B
不同的静态values
对象。
但是,所有这些都带来了成本。在上面的例子中,子类Base
不可能访问相同的静态对象,而所有的子类都不知道对方先验。例如。 B
无法访问与A
相同的values
对象。当您希望所有子类共享值时,一种可能的解决方法是使用Base<agreed-upon-type>.values
。
[C#虚拟(或抽象)静态方法]的可能重复(http://stackoverflow.com/questions/763344/c-sharp-virtual-or-abstract-static-methods) –
@JasonWatkins。感谢标记为dup。每个http://meta.stackoverflow.com/questions/314210/should-i-ask-a-new-question-in-order-to-make-the-answer-easier-to-find我应该做到这一点 –