返回值形式匿名方法

时间:2015-08-27 12:45:16

标签: c#

我有类似的东西。我如何以匿名方式返回值? 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);
        }

    }
}
}

4 个答案:

答案 0 :(得分:1)

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

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

您可以这样称呼它:

Add(m => ReturnRate = m);

这是一种Callback function,可用于一种异步编程。但是,您可能值得花时间阅读async and await。如果您可以向我们提供有关您的方案的确切内容的更多信息,我们可能会为您提供更多提示。

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

然而,这取决于您想要达到的用途。

答案 3 :(得分:-1)

你应该使用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;
        });


    }