泛型委托的扩展方法

发布于 2024-11-18 00:20:01 字数 1253 浏览 3 评论 0原文

我正在重构一些使用具有输出参数的方法的代码。我并不是特别反对输出参数,但对于我正在做的事情,我很少需要多个输出值。

我有六个具有相同签名的方法“void GetThings(T thing, out x, out y)”,

所以我想要简单的方法来表达“gotY = NewMethod(T thing)”,

我想出了这个。待解决的问题:

    [TestFixture]
public class TestsBase
{
    [Test]
    public void Test1()
    {
        Del.ImaExtMethod(2);
        Del2.ImanotherExtMethod(2);
    }

    public static MyDel Del = TestTest;
    public static MyDel2<int> Del2 = TestTest;

    public static void TestTest(int input, out int output)
    {
        output = input * 2;
    }
}

public delegate void MyDel(int input, out int output);
public delegate void MyDel2<T>(T input, out T output);

public static class TestExts
{
    public static int ImaExtMethod(this MyDel del, int input)
    {
        int result;
        del(input, out result);
        return result;
    }

    public static T ImanotherExtMethod<T>(this MyDel2<T> del, T input)
    {
        T result;
        del(input, out result);
        return result;
    }
}

现在我有点左右为难。一方面,这是一个相当优雅的解决方案,另一方面,如果您以前没有见过这种风格,那么它并不完全直观。

那么,在我再次把它撕下来并做其他事情之前,你有什么想法?您将如何解决上述重构问题?我的第三个选择是返回一个有效负载类,其中包含所有输出参数设置属性。它可能比我上面所做的更清晰,但感觉不那么……有趣?……

是的,我就是那个一直说“清晰胜过简洁”的人:/

I was refactoring some code which uses methods that have out parameters. I'm not particularly anti out parameters, but for what I'm doing I rarely need more than one of the values outed.

I have half a dozen methods with the same signature "void GetThings(T thing, out x, out y)"

so I wanted easy ways of saying "gotY = NewMethod(T thing)"

I came up with this. Questions to follow:

    [TestFixture]
public class TestsBase
{
    [Test]
    public void Test1()
    {
        Del.ImaExtMethod(2);
        Del2.ImanotherExtMethod(2);
    }

    public static MyDel Del = TestTest;
    public static MyDel2<int> Del2 = TestTest;

    public static void TestTest(int input, out int output)
    {
        output = input * 2;
    }
}

public delegate void MyDel(int input, out int output);
public delegate void MyDel2<T>(T input, out T output);

public static class TestExts
{
    public static int ImaExtMethod(this MyDel del, int input)
    {
        int result;
        del(input, out result);
        return result;
    }

    public static T ImanotherExtMethod<T>(this MyDel2<T> del, T input)
    {
        T result;
        del(input, out result);
        return result;
    }
}

Now I'm a bit torn. On the one hand it's a reasonably elegant solution, on the other hand it's not exactly intuitive if you haven't seen this style before.

So before I rip it out again and do something else what are your thoughts? How would you tackle the above refactoring? My third option is to return a payload class with all the out parameters setting properties on it. It's probably clearer than what I've done above, but feels less... fun?...

Yes, I'm the same person who keeps saying "Clarity trumps brevity" :/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独守阴晴ぅ圆缺 2024-11-25 00:20:01

就我个人而言,我认为与您所做的类似,但避免使用扩展方法会更清楚。这样做的优点是您不需要将方法分配给显式委托引用,虽然它不太有趣,但我个人认为它更容易阅读:

public delegate void SingleInDualOut<TIn, TOut, TOut2>(TIn input, out TOut out1, out TOut2 out2);

public static class DelegateHelper
{
    public static TOut FirstOutputParam<TIn, TOut, TOut2>(SingleInDualOut<TIn, TOut, TOut2> del, TIn input)
    {
        TOut out1;
        TOut2 out2;

        del(input, out out1, out out2);

        return out1;
    }

    public static TOut2 SecondOutputParam<TIn, TOut, TOut2>(SingleInDualOut<TIn, TOut, TOut2> del, TIn input)
    {
        TOut out1;
        TOut2 out2;

        del(input, out out1, out out2);

        return out2;
    }
}

public static class DelegateTest
{
    public static void TestMethod(int input, out int output1, out int output2)
    {
        output1 = input * 2;
        output2 = input * 3;
    }
}

然后像这样调用它:

DelegateHelper.FirstOutputParam<int, int, int>(DelegateTest.TestMethod, 1);

Personally, I think its clearer to do similar to what you have done, but to avoid the use of extension methods. This has the advantage that you don't need to assign your method to an explicit delegate reference, and though its less fun, personally I think its easier to read:

public delegate void SingleInDualOut<TIn, TOut, TOut2>(TIn input, out TOut out1, out TOut2 out2);

public static class DelegateHelper
{
    public static TOut FirstOutputParam<TIn, TOut, TOut2>(SingleInDualOut<TIn, TOut, TOut2> del, TIn input)
    {
        TOut out1;
        TOut2 out2;

        del(input, out out1, out out2);

        return out1;
    }

    public static TOut2 SecondOutputParam<TIn, TOut, TOut2>(SingleInDualOut<TIn, TOut, TOut2> del, TIn input)
    {
        TOut out1;
        TOut2 out2;

        del(input, out out1, out out2);

        return out2;
    }
}

public static class DelegateTest
{
    public static void TestMethod(int input, out int output1, out int output2)
    {
        output1 = input * 2;
        output2 = input * 3;
    }
}

then call it like this:

DelegateHelper.FirstOutputParam<int, int, int>(DelegateTest.TestMethod, 1);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文