2

ラムダ式が定義されている関数内のローカル値を参照するラムダ式を使用して構造体に値を設定するのに問題があります。私の理解が正しければラムダ関数で構造体を値渡ししているのですが、参照渡しにしたいです。どうやったらよいかわかりません。

テストコード:

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 内の構造体をクラスとして動作させる方法を望んでいます。クラスに変更しないもう 1 つの理由は、一部の構造体が深くネストされており、必要以上に更新に手間がかかることです。

4

2 に答える 2

6

参照によって構造体を渡したい場合は、refパラメーターを持つ独自のデリゲート型が必要です (これは標準のセットにはありませんAction<>) Func<>

また、ラムダを使用する場合、コンパイラはrefおよびoutパラメータの型を推測できないため、それらを明示的に宣言するか、古き良き匿名デリゲート構文を使用する必要があります (宣言された型を持つラムダと非常によく似ています)。

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 に答える