web-dev-qa-db-ja.com

C#での参照によるオブジェクトとオブジェクトのリストの受け渡し

オブジェクトを変更するデリゲートがあります。呼び出し元のメソッドからデリゲートにオブジェクトを渡しますが、呼び出し元のメソッドはこれらの変更を取得しません。 Listをオブジェクトとして渡すと、同じコードが機能します。

すべてのオブジェクトは参照によって渡されるため、変更は呼び出しメソッドに反映されると思いました。あれは正しいですか?

refオブジェクトをデリゲートに渡すようにコードを変更できます。しかし、なぜこれが必要なのか疑問に思っています。またはそれは?

public class Binder
{
    protected delegate int MyBinder<T>(object reader, T myObject);

    public void BindIt<T>(object reader, T myObject)
    {
        //m_binders is a hashtable of binder objects
        MyBinder<T> binder = m_binders["test"] as MyBinder<T>;
        int i = binder(reader, myObject);
    }
}

public class MyObjectBinder
{
    public MyObjectBinder()
    {
        m_delegates["test"] = new MyBinder<MyObject>(BindMyObject);
    }

    private int BindMyObject(object reader, MyObject obj)
    {
        obj = new MyObject
        {
            //update properties
        };
        return 1;
    }
}

///calling method in some other class
public void CallingMethod()
{
    MyObject obj = new MyObject();

    MyObjectBinder binder = new MyObjectBinder();
    binder.BindIt(myReader, obj); //don't worry about myReader

    //obj should show reflected changes
}

更新:

ref内で新しいオブジェクトをインスタンス化するときに、BindMyObjectによってデリゲートにオブジェクトを渡します。

protected delegate int MyBinder<T>(object reader, ref T myObject);
40
David

オブジェクトは参照渡しされません。オブジェクトはまったく渡されません。

デフォルトでは、引数の値は値で渡されます-その値が値型の値または参照であるかどうか。オブジェクトがその参照を介して変更された場合、その変更は呼び出し元のコードにも表示されます。

最初に示したコードでは、refを使用する理由はありませんでした。 refキーワードは、parameterの値を変更するメソッドが必要な場合(たとえば、別のオブジェクトを完全に参照するため)に使用し、その変更を呼び出し元に表示する場合に使用します。

これで、(元々)示したコードには次のコードしかありません:

private int BindMyObject(object reader, MyObject obj)
{
    //make changes to obj in here
}

このようなコードを意味しますか:

private int BindMyObject(object reader, MyObject obj)
{
    obj = new MyObject();
}

またはこのようなコード:

private int BindMyObject(object reader, MyObject obj)
{
    obj.SomeProperty = differentValue;
}

?後者の場合、refは必要ありません。前者の場合、値が参照するオブジェクトに変更を加えるのではなく、パラメーター自体を変更するため、do need refが必要です。実際、justを読むことなくobjの値を設定している場合、outの代わりにrefを使用する必要があります。

問題を実証する短いcompleteプログラムを表示できれば、何が起こっているかを説明するのがずっと簡単になります。

ほんの数段落でこのトピックの正義を行うのは難しいので、 それについての記事全体 があります。

105
Jon Skeet