C#虚拟(或抽象)静态方法
静态继承的工作原理与实例继承类似。除非不允许将静态方法设置为虚拟或抽象C#虚拟(或抽象)静态方法,c#,inheritance,C#,Inheritance,静态继承的工作原理与实例继承类似。除非不允许将静态方法设置为虚拟或抽象 class Program { static void Main(string[] args) { TestBase.TargetMethod(); TestChild.TargetMethod(); TestBase.Operation(); TestChild.Operation(); } } class TestBase { pu
class Program {
static void Main(string[] args) {
TestBase.TargetMethod();
TestChild.TargetMethod();
TestBase.Operation();
TestChild.Operation();
}
}
class TestBase {
public static void TargetMethod() {
Console.WriteLine("Base class");
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
public static new void TargetMethod() {
Console.WriteLine("Child class");
}
}
这将输出:
Base class
Child class
Base class
Base class
但我想:
Base class
Child class
Base class
Child class
如果我可以使用静态方法,我会使TargetMethod成为虚拟的,它会完成这项工作。但是有没有办法达到同样的效果呢
编辑:是的,我可以将操作的副本放在子类中,但这需要将大量代码复制并粘贴到每个子类中,在我的情况下,这大约是35个类,是维护的噩梦。不,不能重写静态方法。“static”还意味着它是由编译器静态绑定的,因此在运行时找不到要调用的实际方法,而是在编译时绑定
您应该做的是使类非静态。使方法虚拟化并覆盖它,充分利用真实继承。然后,如果您真的需要它,就为类的引用创建一个静态入口点。例如,静态工厂、singleton(在大多数情况下,它是一种反模式,但与静态类一样好)或只是一个静态属性。您可以将TargetMethod存储为委托,子类可以根据需要进行更改:
class TestBase {
protected static Action _targetMethod;
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Base class");
});
}
public static void TargetMethod() {
_targetMethod();
}
public static void Operation() {
TargetMethod();
}
}
class TestChild : TestBase {
static new() {
_targetMethod = new Action(() => {
Console.WriteLine("Child class");
});
}
}
由于这些都是静态实例,因此-\u targetMethod
在所有实例中共享-TestChild
中更改它也会更改TestBase
。你可能在乎,也可能不在乎。如果这样做,泛型或字典可能会有所帮助
不过,总的来说,如果您不坚持静态,或者不使用组合而不是继承,您的工作会轻松得多 如果您希望使用抽象静态方法,那么这是可行的,而且对我来说是最容易适应的解决方案:
class TestBase<ChildType> where ChildType : TestBase<ChildType> {
//public static abstract void TargetMethod();
public static void Operation() {
typeof(ChildType).GetMethod("TargetMethod").Invoke(null, null);
}
}
class TestChild : TestBase<TestChild> {
public static void TargetMethod() {
Console.WriteLine("Child class");
}
}
类TestBase,其中ChildType:TestBase{
//公共静态抽象void TargetMethod();
公共静态无效操作(){
typeof(ChildType).GetMethod(“TargetMethod”).Invoke(null,null);
}
}
类TestChild:TestBase{
公共静态void TargetMethod(){
Console.WriteLine(“子类”);
}
}
但我仍然将Stafan作为解决方案,因为对于任何处于类似情况的人来说,使用实例继承可能是最好的建议。但是我必须为它重写太多的代码
public abstract class Base<T>
where T : Base<T>, new()
{
#region Singleton Instance
//This is to mimic static implementation of non instance specific methods
private static object lockobj = new Object();
private static T _Instance;
public static T Instance
{
get
{
if (_Instance == null)
{
lock (lockobj)
{
if (_Instance == null)
{
_Instance = new T();
}
}
}
return _Instance;
}
}
#endregion //Singleton Instance
#region Abstract Definitions
public abstract T GetByID(long id);
public abstract T Fill(SqlDataReader sr);
#endregion //Abstract Definitions
}
public class InstanceClass : Base<InstanceClass>
{
//empty constructor to ensure you just get the method definitions without any
//additional code executing
public InstanceClass() { }
#region Base Methods
public override InstanceClass GetByID(long id)
{
SqlDataReader sr = DA.GetData("select * from table");
return InstanceClass.Instance.Fill(sr);
}
internal override InstanceClass Fill(SqlDataReader sr)
{
InstanceClass returnVal = new InstanceClass();
returnVal.property = sr["column1"];
return returnVal;
}
}
公共抽象类基类
其中T:Base,new()
{
#区域单例实例
//这是为了模拟非实例特定方法的静态实现
私有静态对象lockobj=新对象();
私有静态T_实例;
公共静态T实例
{
得到
{
if(_Instance==null)
{
锁(lockobj)
{
if(_Instance==null)
{
_实例=新的T();
}
}
}
返回_实例;
}
}
#endregion//Singleton实例
#区域抽象定义
公共摘要T GetByID(长id);
公共摘要T填充(SqlDataReader sr);
#endregion//抽象定义
}
公共类InstanceClass:基
{
//空构造函数以确保只获取方法定义,而不包含任何
//执行附加代码
公共InstanceClass(){}
#区域基方法
公共重写InstanceClass GetByID(长id)
{
SqlDataReader sr=DA.GetData(“从表中选择*);
返回InstanceClass.Instance.Fill(sr);
}
内部重写InstanceClass填充(SqlDataReader sr)
{
InstanceClass returnVal=新InstanceClass();
returnVal.property=sr[“column1”];
返回值;
}
}
我认为这将是一个可行的解决方案,可以在不破坏太多纯粹的OO原则的情况下完成您想要做的事情。为什么要使用静态函数?您将继承与查找和名称隐藏混淆了。可能重复的