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 p开发者_如何学运维roperties 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" :/
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);
精彩评论