【问题标题】:Override Method Group On-The-Fly即时覆盖方法组
【发布时间】:2016-11-19 16:38:03
【问题描述】:

我有一个实现接口的基类:

internal interface ITest
{
    virtual void GetData();
}

internal class Test : ITest
{
    public void GetData()
    {
        Console.WriteLine("Test - Hello World!");
    }
}

通过继承Test类并覆盖GetData()方法来使用:

internal class SubTest : Test
{
    public override void GetData()
    {
        Console.WriteLine("SubTest - Hello World!");
    }
}

我有数百个存储过程,每个都需要调用 1 次。为每个从 Test 继承的存储过程创建一个像 SubTest 这样的新类似乎有点过头了。

有没有办法编写 Lambda 表达式、匿名方法或动作,让我覆盖空的默认方法?

我的想法是这样的:

var t = new Test();
t.GetData = delegate()
{
    Console.WriteLine("Anonymous - Hello World!");
};

有没有办法为这样的方法 on-the-fly 编写覆盖?

解决了!

我使用 Evk 的技术来应用 Gusman 展示的内容:

internal interface ITest
{
    virtual void GetData();
}

internal class Test : ITest
{
    public void GetData()
    {
        Console.WriteLine("Call from Test");
    }
}

internal class SubTest : Test
{
    private readonly Action _localTest;
    public SubTest(Action localTest)
    {
        _localTest = localTest;
    }
    public override void GetData()
    {
        base.GetData();
        _localTest();
    }
}

这是我的实现方式:

class ClassTester
{
    public void Run()
    {
        var t = new Test(() =>
            {
                Console.WriteLine("Anonymous Override of Test");
            }
        );
        t.GetData();
    }
}

【问题讨论】:

  • 鉴于Test 没有实现,它甚至不应该是一个类。只需让派生自它的类实现接口即可。
  • @Servy - 为了这个例子,我在上面放了一些简单的东西。它不是我们完整的公司数据库类。我应该添加详细信息吗?
  • @Servy,我编辑了问题以显示每个方法的调用位置。
  • 你可以创建一个类,它的GetData 方法简单地执行一个委托,通过公共属性设置(或在ctor中传递)。
  • @jp2code 我感觉到你的痛苦,但你要做的任何事情都需要改变类和接口。

标签: c# inheritance


【解决方案1】:

如果我理解正确,你可以这样做

class DynamicTest : Test {
    private readonly Action _getData;
    public DynamicTest(Action getData) {
        _getData = getData;
    }
    public override void GetData() {
        _getData();
    }
}

然后

var test = new DynamicTest(() => {
      Console.WriteLine("Dynamic");
});

【讨论】:

  • 我赢了2秒! XD
  • @Gusman true :) 虽然我们的答案有些不同,所以我还是留下我的答案。
  • {GASP!} 成功了! ...嗯,它下面没有任何红色波浪线,至少。让我测试一下......
【解决方案2】:

好吧,如果你只是希望能够分配一些外部函数,那么重新定义你的接口,而不是函数使用一个动作:

internal interface ITest
{
    Action GetData{ get; set; }
}

internal class Test : ITest
{
    public Action GetData  { get; set; }
}

然后你就可以为所欲为:

var t = new Test();
t.GetData = () =>
{
    Console.WriteLine("Anonymous - Hello World!");
};

你可以这样称呼它

t.GetData();

【讨论】:

    【解决方案3】:

    将要执行的存储过程的名称传递给方法Test

    简单才是王道。

    internal interface ITest
    {
        virtual void GetData(string spname);
    }
    
    internal class Test : ITest
    {
        public void GetData(string spname)
        {
            Console.WriteLine("Executing store proc: " + spname);
        }
    }
    

    【讨论】:

    • 假设界面不能改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-24
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    相关资源
    最近更新 更多