2

我在使用 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 中的结构表现为一个类。不更改为类的另一个原因是某些结构嵌套得很深,并且需要花费更多的精力来更新,而不是我认为应该有的必要。

4

2 回答 2

6

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

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

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);
}
于 2012-06-07T20:39:14.570 回答
2

将结构放在持有者类中并传递持有者类的实例。

public class SomeStructHolder
{
    public someStruct theStruct;
}
于 2012-06-07T20:32:42.033 回答