【问题标题】:Overriding virtual methods when instantiating a class实例化类时重写虚方法
【发布时间】:2013-05-24 18:16:29
【问题描述】:

我有一个带有一些虚函数的类,让我们假设这是其中之一:

public class AClassWhatever
{
    protected virtual string DoAThingToAString(string inputString)
    {
        return inputString + "blah";
    } 
}

我想在重写“DoAThingToAString”内联的同时实例化这个类,就像我可以在声明中内联声明属性一样,如下所示:

...

AClassWhatever instance = new AClassWhatever
{
    DoAThingToAString = new function(string inputString)
    {
        return inputString + inputString + " fill my eyes."
    }
}

...

现在对于“实例”,DoAThingToAString 被该定义覆盖。我需要能够在类定义中定义默认行为,并且只根据需要覆盖它,不同的时间不同,我不想增加一堆子类来做到这一点。

我知道我需要使用委托或类似的东西,但我已经离开语法游戏太久了,而且谷歌给了我太多不相关的信息。

【问题讨论】:

    标签: c#


    【解决方案1】:

    您可以使用委托或Funcs 来执行此操作。

    首先,将此添加到您的 AClassWhatever 类中:

    public Func<string, string> DoAThingToAString = (x) => x + "blah";
    

    现在您可以使用相同的语法来覆盖操作。

    AClassWhatever instance = new AClassWhatever()
    {
        DoAThingToAString = (x) => x + x + " fill my eyes."
    };
    

    【讨论】:

    • 这是我正在寻找的语法,但愚蠢的问题。在 DoAThingToAString 中,我正在使用从控制器操作调用的控制器扩展方法:this.DoExtensionMethod(someString); 现在我在 Func 定义中,不再引用“this”。有没有办法获得对调用者的引用,或者我必须将它与我的其他输入一起传递?
    • @kamii,您必须传入对该对象的引用,或您需要的任何其他特定值。这是一个匿名函数,因此它不知道实例。 (请事实检查我)。
    【解决方案2】:

    你不能用方法来做,但你可以用委托/匿名方法做同样的事情:

    public class AClassWhatever
    {
        public AClassWhatever()
        {
            this.DoAThingToAString = this.DoAThingToAStringImpl;
        }
    
        public Func<string, string> DoAThingToAString { get; set; }
    
        protected virtual string DoAThingToAStringImpl(string input)
        {
            return input + input + " fill my eyes.";
        }
    }
    

    用法:

    var instance = new AClassWhatever
    {
        DoAThingToAString = inputString => inputString + inputString +
            " fill my eyes something other than the default behavior."
    }
    
    var result = instance.DoAThingToAString("input");
    

    注意inputString =&gt; inputString + inputString + "..."x =&gt; x + x + "..."是一样的

    【讨论】:

    • "我需要能够在类定义中定义默认行为..."
    • @mellamokb 我更改了答案以在构造函数中提供默认实现。
    • 由于更好​​的编码,我给你答案,但也许你对我在 cmets 中问 gunr2171 的调用者参考问题有答案?
    • @kamii 而不是使用 this 指针,只使用引用本身。
    • @Dan,我认为他的问题是,在重载函数时,他将无法在函数内使用其实例变量的私有成员。
    【解决方案3】:

    为什么不定义委托属性并在调用方法时使用该定义(如果它存在)?在对象的实例化中,您可以使用该属性提供替代定义。

    例如:

    public MyDelegateTypeThatMatchesMyFunctionCall DoAThingToAStringProperty { get; set; }
    
    public class AClassWhatever
    {
        protected virtual string DoAThingToAString(string inputString)
        {
            var handler = this.DoAThingToAStringProperty;
            if (handler)
            {
                return handler(inputString);
            }
    
            // do default behavior
            return inputString + "blah";
        } 
    }
    

    如果你想确保你的委托属性覆盖任何被覆盖的虚方法定义,你可以这样做:

    public MyDelegateTypeThatMatchesMyFunctionCall DoAThingToAStringProperty { get; set; }
    
    public class AClassWhatever
    {
        protected string DoAThingToAString(string inputString)
        {
            var handler = this.DoAThingToAStringProperty;
            if (handler)
            {
                return handler(inputString);
            }
    
            // do default behavior
            return DoAThingToAStringInternal(inputString);
        } 
    
        protected virtual string DoAThingToAStringInternal(string inputString)
        {
            // do default behavior
            return inputString + "blah";
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-06
      • 2018-05-14
      • 2016-10-05
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多