【问题标题】:Get reference to class that called virtual method获取对调用虚方法的类的引用
【发布时间】:2018-03-27 20:27:03
【问题描述】:

是否可以从抽象类中定义的方法中获取对调用虚拟方法的类的引用?

基本上,我有一个抽象类,比如说 BaseAction,它包含一个名为 RetrieveData 的虚拟方法:

public abstract class BaseAction
{
    protected virtual void RetrieveData()
    {

    }
}

在实现中,我把这个虚方法作为一个Action传入一个方法,大意是这样的:

public class Action: BaseAction
{
    public Action()
    {
        ActionStatement(RetrieveData);
    }
}

有可能在 RetrieveData 方法中获得对 Action 类的引用,而不必在 Action 类中重写它,效果如下:

public abstract class BaseAction
{
    protected virtual void RetrieveData()
    {
        // using reflection to get a handle on instance of Action?
    }
}

这样做的原因是,我想在各种不同类型的类中使用这个虚拟方法,每个类都有一个需要修改的 ID 字段,但我不想在每个类中都覆盖这个虚拟方法20 多个动作类,只是为了更改 ID 字段。

我希望这发生在基类中,以限制代码重复的数量。

【问题讨论】:

  • 不可以,但是可以传入对象实例。
  • 你能弄清楚“调用虚方法的类”是什么意思吗?类不调用方法,方法是从(可能不同的)对象中的其他方法调用对象。
  • 不确定这个问题,但使用generics 并使用constrains 抽象generic type 也许可以帮助你。
  • 为什么不向基类添加 ID 属性?
  • 调用protected 方法的对象在当前方法中始终可用this。它是派生类。

标签: c# reflection


【解决方案1】:

您不需要对此进行反思。你有很多选择:

如果ID字段在每个实现的类中都是通用的,只需在抽象类中声明,并在RetrieveData()方法中更改值即可。

public abstract class BaseAction
{
    protected int ID;
    protected virtual void RetrieveData()
    {

    }
}

如果 ID 字段并非在所有实现的类中通用,您可以添加一个抽象方法并使用该方法访问 ID 属性。

public abstract class BaseAction
{
    protected abstract ChangeID(int value);
    protected virtual void RetrieveData()
    {
        //Do your stuff

        ChangeID(<with-new-value>);
    }
}

public class Action: BaseAction
{
    Protected override ChangeID(int value)
    {
        //Do whatever you want
    }

    public Action()
    {
        ActionStatement(RetrieveData);
    }
}

【讨论】:

    【解决方案2】:

    如果你这样做:

    public abstract class BaseAction
    {
        protected void Foo()
        {
            Console.WriteLine(this.GetType());
        }
    }
    
    public class Action : BaseAction 
    {
        public void Bar() 
        {
            Foo();
        }
    }
    
    // the runtime type of foo will be Action regardless of compile-time type
    BaseAction foo = new Action(); 
    foo.Bar();
    

    它将输出Action - 也就是说,在继承方法(Foo())中,如果方法最终是通过 运行时键入Action

    (暂时忽略方法上的 new 修饰符或显式接口实现。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多