从匿名方法返回值

本文关键字:返回值 方法 | 更新日期: 2023-09-27 18:10:01

我有这样的东西。我怎么能返回值形式匿名方法?returnRate = d;。例如,让我有一些类得到的消息从服务器。我想在CarsBicycles类中处理这些消息,现在清楚了吗?

namespace ConsoleApplication9
{
class Program
{
    static void Main(string[] args)
    {
        Cars c = new Cars();
        Bicycles b = new Bicycles();
    }
}
public class Cars
{
    public Cars()
    {
        GetData G1 = new GetData();
        Dictionary<string, string> D1 = new Dictionary<string, string>();
        G1.ProcessCars(ref D1);
    }
}
public class Bicycles
{
    public Bicycles()
    {
        GetData G2 = new GetData();
        Dictionary<string, string> D2 = new Dictionary<string, string>();
        G2.ProcessBicycles(ref D2);
    }
}
public class Singleton
{
    private static Singleton instance;
    public Dictionary<string, Action<MessageEventArgs>> Handle;
    private Singleton() 
    {
        Handle = new Dictionary<string, Action<MessageEventArgs>>();
    }
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
}
public class GetData
{
    private Client socket;
    public GetData()
    {
        socket = new Client("http://echo.jsontest.com/bicycles/10");
        socket.Message += Message;
    }
    public void ProcessBicycles(ref Dictionary<string, string> returnRate)
    {
        Singleton.Instance.Handle.Add("bicycles", (m) => 
        {
            Dictionary<string, string> d = m.Message.Json.GetFirstArgAs<Dictionary<string, string>>() as Dictionary<string, string>;
            //returnRate = d;
        });
    }
    public void ProcessCars(ref Dictionary<string, string> returnRate)
    {
        Singleton.Instance.Handle.Add("cars", (m) =>
        {
            Dictionary<string, string> d = m.Message.Json.GetFirstArgAs<Dictionary<string, string>>() as Dictionary<string, string>;
            //returnRate = d;
        });
    }
    private void Message(object sender, MessageEventArgs e)
    {
        if (Singleton.Instance.Handle.ContainsKey(e.Message.Event))
        {
            Singleton.Instance.Handle[e.Message.Event](e);
        }
    }
}
}

从匿名方法返回值

您必须自己传递Action,而不是使用ref参数创建它。所以你的Add方法变成了:

public void Add(Action<string> action) {
    Handle.Add("1", action);
}

你可以这样调用它:

Add(m => ReturnRate = m);

这是一种Callback函数,可以用于一种异步编程。然而,花时间阅读async和await可能是值得的。如果你能给我们更多的信息,关于你的场景到底是什么,我们也许能给你更多的提示。

如果你必须使用ref参数(出于一些奇怪的原因),我认为你运气不好…

您应该使用Func<string,string>代替Action

Action<string>表示void function(string s)Func<string,string>表示string function(string s)

这是因为在匿名方法体中使用但在它之外的变量将是编译器生成的类中的公共字段。但是你可以引入一个局部变量使其可编译:

public void Add(ref string rate)
{
    string r = rate;
    Handle.Add("1", (m) => 
    { 
        Console.WriteLine(m);
        r = m;
    });
    rate = r;
}

编译器会在后台生成如下内容:

public void Add(ref string rate)
{
    <>c__DisplayClass1 CS$<>8__locals2 = new <>c__DisplayClass1();
    CS$<>8__locals2.r = rate;
    this.Handle.Add("1", new Action<string>(CS$<>8__locals2.<Add>b__0));
    rate = CS$<>8__locals2.r;
}
[CompilerGenerated]
private sealed class <>c__DisplayClass1
{
    public string r;
    public void <Add>b__0(string m)
    {
        Console.WriteLine(m);
        this.r = m;
    }
}

注意:虽然可以编译,但它不会像您期望的那样工作,因为调用外部Add不会执行Handle.Add添加的委托。要从内部委托返回m,你必须使用Func来代替。

您应该使用Func<string,string> (delegate Func<in T,out TResult>),它相当于一些接受字符串并返回字符串的函数

例如:-

private string MyFunction(string inputstring){}

Action<string> (delegate Action<in T>)对应的函数只接受输入,不返回任何值

    private void MyFunction(string inputstring){}

你可以把你的代码修改成

    private Dictionary<string, Func<string,string>> Handle;
    private string ReturnRate;
    public data()
    {
        Handle = new Dictionary<string, Func<string,string>>();
        Add(ref ReturnRate);
        Handle["1"]("MyValue");

        Console.WriteLine(ReturnRate);
    }
    public void Add(ref string rate)
    {
      string somevalue=rate;
        Handle.Add("1", (m) =>
        {
             Console.WriteLine(m);
            somevalue= m;
            return m;
        });

    }