【问题标题】:Is there a way to save a method in a variable then call it later? What if my methods return different types?有没有办法将方法保存在变量中,然后再调用它?如果我的方法返回不同的类型怎么办?
【发布时间】:2011-10-05 10:47:27
【问题描述】:

编辑:感谢您的回答。我目前正在努力!\

我有3个方法,S()返回字符串,D()返回double,B()返回bool。

我还有一个变量来决定我使用哪种方法。 我想这样做:

    // I tried Func<object> method; but it says D() and B() don't return object.
    // Is there a way to use Delegate method; ? That gives me an eror saying method group is not type System.Delegate
    var method;

    var choice = "D";

    if(choice=="D")
    {
        method = D;
    }
    else if(choice=="B")
    {
        method = B;
    }
    else if(choice=="S")
    {
        method = S;
    }
    else return;

    DoSomething(method); // call another method using the method as a delegate.

    // or instead of calling another method, I want to do:
    for(int i = 0; i < 20; i++){
       SomeArray[i] = method();
    }

这可能吗?

我读了这篇文章: Storing a Method as a Member Variable of a Class in C# 但是我需要存储具有不同返回类型的方法...

【问题讨论】:

  • 我很感兴趣,你为什么要传递一个方法而不是在一个你可以按需访问的范围内声明它?
  • 其实我需要的方法是静态的,所以可以访问。只是我需要根据选择中的值选择一个来使用,而不是每次通过循环都对选择进行 if-elseif 检查。
  • 您需要实际声明一个委托。这将允许您在 C# 中模拟函数指针,就像在 C 或 C++ 中找到它们一样。

标签: c# methods delegates


【解决方案1】:

好吧,你可以这样做:

Delegate method;

...
if (choice == "D") // Consider using a switch...
{
    method = (Func<double>) D;
}

然后 DoSomething 将被声明为 Delegate,这不是很好。

另一种选择是将方法包装在一个委托中,该委托只执行所需的任何转换以将返回值作为object

Func<object> method;


...
if (choice == "D") // Consider using a switch...
{
    method = BuildMethod(D);
}

...

// Wrap an existing delegate in another one
static Func<object> BuildMethod<T>(Func<T> func)
{
    return () => func();
}

【讨论】:

  • 不错的解决方案。您还可以将 BuildMethod 限制为仅将值类型作为 T,因为返回引用类型的方法将可以通过协变的方法组到委托的转换分配给 Func
  • @Eric:除了返回可空值类型的方法,它既不能满足where T : struct 约束,也不能使用泛型协方差;)
  • @Jon:好点。我总是忘记可空类型不满足值类型约束。
  • @Eric:我承认这不是不包括约束的原因......但事后听起来不错:)
  • 带参数的方法呢?
【解决方案2】:
Func<object> method;

var choice = "D";

if(choice=="D")
{
    method = () => (object)D;
}
else if(choice=="B")
{
    method = () => (object)B;
}
else if(choice=="S")
{
    method = () => (object)S;
}
else return;

DoSomething(method); // call another method using the method as a delegate.

// or instead of calling another method, I want to do:
for(int i = 0; i < 20; i++){
   SomeArray[i] = method();
}

【讨论】:

    【解决方案3】:
    private delegate int MyDelegate();
    private MyDelegate method;
    
    
        var choice = "D";
    
        if(choice=="D")
        {
            method = D;
        }
        else if(choice=="B")
        {
            method = B;
        }
        else if(choice=="S")
        {
            method = S;
        }
        else return;
    
        DoSomething(method); 
    

    【讨论】:

    • 这些方法不返回int,所以这不会编译。另外,为什么要声明自己的Func&lt;int&gt; 版本?
    猜你喜欢
    • 2020-06-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    • 1970-01-01
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    相关资源
    最近更新 更多