首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有可变数目参数的匿名方法

具有可变数目参数的匿名方法
EN

Stack Overflow用户
提问于 2016-02-03 04:59:46
回答 2查看 525关注 0票数 2

我正在尝试创建一个使用带参数的函数的扩展方法。我想支持可变数量的参数(none,1,2,...10)

我有一个类似的东西,它恰好适用于三个参数。我如何简化它以支持可变数量的参数,而不必对每个排列都进行复制和粘贴?这有可能吗?

(注意:我的示例非常简单。我的实际实现有更多的逻辑,例如支持具有计数、Thread.Sleep、跟踪日志记录、异常处理等的“重试”逻辑。)

谢谢!

代码语言:javascript
复制
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.
        }
    }
}

它是这样调用的:

代码语言:javascript
复制
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");
}
EN

回答 2

Stack Overflow用户

发布于 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[],这完全违背了泛型的观点。尽管你可能愿意放弃类型检查,如果你真的有一个未知数量的参数,可能是不切实际的高。

票数 2
EN

Stack Overflow用户

发布于 2016-02-03 06:28:31

你不能这么做。另一种方法是创建一个接受一个参数的扩展方法,但该参数可以由匿名函数组成。因此,您的调用代码将完全控制如何使用它。不是最干净的,但至少比代码生成器路线干净一点:

代码语言:javascript
复制
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);
    }
}

用法:

代码语言:javascript
复制
var param1 = 1;
var param2 = "string";

Func<bool> function = () => 
{
    // do stuff with param1 and param2
    return true;
}

var results = function.Execute();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35163687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档