我正在尝试创建一个使用带参数的函数的扩展方法。我想支持可变数量的参数(none,1,2,...10)
我有一个类似的东西,它恰好适用于三个参数。我如何简化它以支持可变数量的参数,而不必对每个排列都进行复制和粘贴?这有可能吗?
(注意:我的示例非常简单。我的实际实现有更多的逻辑,例如支持具有计数、Thread.Sleep、跟踪日志记录、异常处理等的“重试”逻辑。)
谢谢!
public static class UtilExtensions
{
public static TResult Execute<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function, T1 argument1, T2 argument2, T3 argument3))
{
// do other stuff ... like logging
try
{
// call our 'action'
TResult result = function(argument1, argument2, argument3);
return result;
}
catch (Exception ex)
{
// do other stuff ... like logging, handle Retry logic, etc.
}
}
}它是这样调用的:
public string DoSomething(int arg1, string arg2, MyObject arg3)
{
if (arg1 == 1)
throw new Exception("I threw an exception");
return "I ran successfully";
}
public string DoSomethingElse()
{
return "blah blah blah";
}
public string DoSomethingMore(DateTime dt)
{
return "hi mom";
}
[TestMethod]
public void Should_call_UtilsExtensions_Execute_method_successfully()
{
int p1 = 0;
string p2 = "Hello";
MyObject p3 = new MyObject();
string results = UtilExtensions.Execute<int, string, MyObject, string>(
DoSomething, p1, p2, p3);
// ??? So how would I use my UtilExtensions api to call
// DoSomethingElse (no arguments)
// DoSomethingMore (one argument)
// I'm okay to create overloads of my Execute method
// but I don't want to copy-and-paste the same code/logic in each method
results.Should().Be("I ran successfully");
}发布于 2016-02-03 05:54:48
我不认为你能做到这一点,据我所知,这正是Func和Action类型在.Net中对不同参数编号有大量不同声明的原因。查看https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx的左侧
您询问的内容与以下内容类似,但在本例中,OP询问的是接口Can I have a variable number of generic parameters?
这个问题本质上是泛型的基本限制。
你也许可以使用反射来做一些事情,但是我认为你最好选择一些合理的参数来支持和编写重载。
Params不起作用,因为对于params,数组中的所有类型都是相同的类型。T1、T2等有不同的类型可供您使用。您必须将参数声明为Object[],这完全违背了泛型的观点。尽管你可能愿意放弃类型检查,如果你真的有一个未知数量的参数,可能是不切实际的高。
发布于 2016-02-03 06:28:31
你不能这么做。另一种方法是创建一个接受一个参数的扩展方法,但该参数可以由匿名函数组成。因此,您的调用代码将完全控制如何使用它。不是最干净的,但至少比代码生成器路线干净一点:
public static class UtilExtensions
{
public static TResult Execute<TResult>(this Func<TResult> function)
{
// do logging
try
{
TResult result = function();
return result;
}
catch (Exception ex)
{
// do other stuff ... like logging, handle Retry logic, etc.
}
// or throw - this right here could prove unpredictable and is verrrry dirty
return default(TResult);
}
}用法:
var param1 = 1;
var param2 = "string";
Func<bool> function = () =>
{
// do stuff with param1 and param2
return true;
}
var results = function.Execute();https://stackoverflow.com/questions/35163687
复制相似问题