lambda表达式中的struct引用

时间:2012-06-07 20:23:13

标签: c# lambda struct

我在使用lambda表达式设置结构中的值时遇到问题,该表达式引用了定义lambda表达式的函数中的本地值。如果我理解正确,结构在lambda函数中通过值传递,但我希望它通过引用传递。我不知道怎么做。

测试代码:

public struct partialData
{
    public int foo;
}
public struct futureData
{
    public int bar;
}

// if you change this to a class, everything works as desired.
public struct someStruct 
{
    public partialData pd;
    public futureData fd;
}
class Apple
{
    private Action<object> toBeSet;
    public someStruct makeStruct(partialData pd)
    {
        someStruct ss = new someStruct();
        ss.pd = pd;

        toBeSet = new Action<object>(
             (futureValue) => ss.fd = (futureData)futureValue
        );
        return ss;
    }
    public void futureSet(futureData fd)
    {
        toBeSet.Invoke(fd);
    }
}


class Program
{
    static void Main(string[] args)
    {
        partialData pd;
        pd.foo = 1;
        futureData fd;
        fd.bar = 2;
        Apple ap=new Apple();
        someStruct ss= ap.makeStruct(pd);
        ap.futureSet(fd);
        // I'd like it to be 1,2, it results in 1,0
        Console.WriteLine("foo is: "+ss.pd.foo + ", bar is: "+ss.fd.bar);
        Console.In.ReadLine();
    }
}

注意: 结构由其他人编写(并用于互操作),我不能将它们更改为类。我喜欢我当前的设计,所以我希望有一种方法来保持这种设计,但只是让Action中的结构表现为一个类。不改变类的另一个原因是某些结构嵌套得很深,并且需要更多的努力来更新,而不是我认为应该是必要的。

2 个答案:

答案 0 :(得分:6)

如果您想通过引用传递结构,那么您需要具有ref参数的自己的委托类型(不在标准Action<>Func<>的集合中)。

此外,使用lambdas时,编译器无法推断refout参数的类型,因此,您必须明确声明它们或使用良好的旧匿名委托语法(看起来非常类似于声明类型的lambda:)

struct S
{
    public int f;
}

delegate void DoDelegate(ref S s);

public static void M()
{
    var s = new S();

    DoDelegate delegate2 = (ref S st) => st.f = 5;
    DoDelegate delegate1 = delegate(ref S st) { st.f = 10; };

    delegate1.Invoke(ref s);
    delegate2.Invoke(ref s);
}

答案 1 :(得分:2)

将结构放在holder类中,并传递holder类的实例。

public class SomeStructHolder
{
    public someStruct theStruct;
}