但从我的实验来看,它只会迫使直接的孩子实现这些静态抽象成员。那个
static abstract
修饰符不能用于
abstract class
.
对的
我错过什么了吗?为什么会出现这种情况?
-
这是经过设计的。
-
…因为没有理由介绍
静态摘要
的成员
class
类型
-
…因为这样的成员永远无法使用(在受约束的通用上下文之外)。
-
因为
static
成员不会通过虚拟调用(vtable查找)调用,因为没有
this
从中获得vtable引用的引用。
-
…因为
静止的
(
静止的
方法没有隐式
(并且隐藏)
这
参数
举例说明:
class SubclassA : IMyInterface
{
public static void DoSomething() => Console.WriteLine( "Explosive bolts, ten thousand volts, At a million miles an hour" );
}
class SubclassAB : SubclassA
{
public static void DoSomething() => Console.WriteLine( "Life is short and love is always over in the morning." );
}
class SubclassB : IMyInterface
{
public static void DoSomething() => Console.WriteLine( "Hot metal and methedrine." );
}
//
public void Main()
{
MyMethod( new SubclassA() );
MyMethod( new SubclassAB() );
MyMethod( new SubclassB() );
}
public void MyMethod( IMyInterface instance )
{
// At this point, how do you propose invoking `DoSomething`? (without using reflection)
// ...see the problem?
}
然而
interface
类型
做
支持
静态摘要
成员,但这只是因为它们在泛型方法约束的上下文中很有用,因为它允许泛型代码为非虚拟调用站点指定方法:当JIT/运行时实例化它发出的泛型方法时
静止的
方法调用,而不是基于vtable的调用。
(对于Swift用户来说,这是
有点
喜欢如何
protocol
类型不等同于C#或Java
界面
类型,因为
协议
支持对值类型的非装箱调用,而(在非泛型方法中)C#
界面
类型总是被视为引用类型,但无论如何)。
我相信我已经知道我的案例的解决方法,但这种方式并不能强迫每个孩子
MyAbstractClass
实施
IMyInterface
听起来你是在使用接口类型
linter
,以保证一套
班
类型都遵循某种通用编码约定并实现某种通用成员集(在这种情况下,
静止的
成员),即使您从未使用过
界面
在你的程序中的任何位置-但这不是什么
界面
C#中的类型适用于。
而如果你
MyMethod
一种通用方法和用途
IMyInterface
作为一种约束,它变得有用,因为
现在
您可以调用
静止的
方法,方法使用类型参数作为类型名称:
public void MyGenericMethod<T>( T instance )
where T : IMyInterface
{
T.DoSomething();
}
public void Main()
{
GenericMethod<SubclassA>(); // Will print "Explosive bolts, ten thousand volts, At a million miles an hour"
GenericMethod<SubclassAB>(); // <-- This actually behaves the same as SubclassA.
GenericMethod<SubclassB>(); // Will print "Hot metal and methedrine."
}
…尽管与的通话
SubclassAB
行为与
SubclassA
,因为与
AB子类
的呼叫
T.DoSomething()
被路由到
SubclassA.DoSomething()
尽管
SubclassAB.DoSomething()
存在。
……我不知道为什么这还不起作用。
The original proposal document simply puts "TBD" for this
,奇怪的是我找不到
any relevant bugs filed in the Roslyn repo
,所以我会在发现后更新此答案。
我想你可以争辩说
T : BaseClass
约束和
T : IInterface
约束-至少在这个代码(下面)可以说的范围内
应该
被允许工作,但不允许(
CS0704)
public class BaseClass
{
public static void DoSomething() => Console.WriteLine( "Strange men rent strange flowers" );
}
public class DerivedClass : BaseClass
{
public static void DoSomething() => Console.WriteLine( "Mundane by day inane at night" );
}
public static void Main()
{
GenericMethod<AbstractClass>(); // Should print "Strange men rent strange flowers"
GenericMethod<DerivedClass >(); // Should print "Mundane by day inane at night"
}
public static void GenericMethod<T>()
where T : BaseClass
{
Type t = typeof(T);
T.DoSomething(); // CS0704
}