代码之家  ›  专栏  ›  技术社区  ›  Daniel MoÅ¡mondor

从静态方法调用子代虚拟方法

  •  1
  • Daniel MoÅ¡mondor  · 技术社区  · 15 年前

    public abstract class Foo
    {
      public static void StaticMethod()
      {
      }
    }
    public class Bar : Foo
    {
    }
    

    打电话有效吗

    Bar.StaticMethod();
    

    ???

    public abstract class Foo
    {
      public static void StaticMethod()
      {
      }
      public abstract void VirtualMethod();
    }
    public class Bar : Foo
    {
      public override void VirtualMethod()
      {
         Trace.WriteLine("virtual from static!!!!");
      }
    }
    

    嗯,我知道我不能从静态方法调用实例方法。所以问题是:

      public static void StaticMethod()
      {
        derived d=new derived();
        d.VirtualMethod();
      }
    

    顺便说一句,我会在这里支持基于非反射的解决方案!

    2 回复  |  直到 15 年前
        1
  •  6
  •   Community Paul Sweatte    7 年前

    要从静态方法调用非静态方法,必须提供一个实例,因为静态方法没有绑定到 this

    然后,在你编辑之后,你的问题让我想到了 curiously recurring template pattern 在C++中。

    here ,这将为您提供如下信息:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;
    
    namespace ConsoleApplication3
    {
      public abstract class Foo<T> where T : Foo<T>, new()
      {
        public static void StaticMethod()
        {
          T t = new T();
          t.VirtualMethod();
        }
    
        public abstract void VirtualMethod();
      }
    
      public class Bar : Foo<Bar>
      {
        public override void VirtualMethod()
        {
          System.Console.WriteLine("virtual from static!!!!");
        }
      }
      class Program
      {
        static void Main(string[] args)
        {
          Bar.StaticMethod();
        }
      }
    }
    

    并打印出预期的 "virtual from static!!!!"

        2
  •  4
  •   Eric Lippert    15 年前

    是的,调用Bar.StaticMethod是合法的,其行为就像调用Foo.StaticMethod一样。

    我可以从基类的静态方法创建派生类的实例吗。

    好的,我想我明白你想要什么。您想调用一个静态方法,让它创建一个任意派生类的实例,然后在该类上调用一个方法,是吗?

    使用泛型。

    abstract class Foo 
    {
        public static void DoBlah<T>() where T : Foo, new()
        {
            T t = new T();
            t.Blah();
        }
        public abstract void Blah();
    }
    class Bar : Foo
    { 
        public Bar() {}
        public override void Blah() {}
    }
    ...
    Foo.DoBlah<Bar>();