40 votes

C # Passage d'objets et liste d'objets par référence

J'ai un délégué qui modifie un objet. Je passe d'un objet à la délégation à partir d'un appel de méthode, mais la méthode appelante n'a pas de ramassage de ces changements. Le même code fonctionne si je passe une Liste que l'objet. Je pensais que tous les objets sont passés par référence, donc toutes les modifications seront reflétées dans l'appel de la méthode?

Je peux modifier mon code pour passer d'un objet référence au délégué mais je me demande pourquoi est-ce nécessaire?

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
}

Mise à JOUR

J'ai passé des objets par la réf pour le délégué comme je l'ai été de l'instanciation d'un objet à l'intérieur de BindMyObject.

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

105voto

Jon Skeet Points 692016

Les objets ne sont pas passés par référence. Les objets ne sont pas transmis à tous.

Par défaut, la valeur de l'argument est passé par valeur - si cette valeur est une valeur de type valeur ou une référence. Si un objet est modifié par l'intermédiaire de cette référence, alors que le changement sera visible par le code appelant ainsi.

Dans le code que vous avez manifesté à l'origine, il n'y a pas de raison d'utiliser ref. L' ref mot-clé est utilisé lorsque vous voulez une méthode qui modifie la valeur d'un paramètre (par exemple, pour faire référence à un autre objet entièrement) et ont de ce changement visible pour l'appelant.

Maintenant, dans le code que vous avez indiqué (à l'origine), vous avez seulement:

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

Entendez-vous un code comme ceci:

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

ou le code comme ceci:

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

? Si c'est le dernier, alors vous n'avez pas besoin d' ref. Si c'est l'ancien, alors vous ne devez ref parce que vous changez le paramètre lui-même, de ne pas apporter des modifications à l'objet que la valeur se réfère. En fait, si vous êtes juste de définir la valeur de obj sans jamais le lire, vous devez utiliser out au lieu de ref.

Si vous pouvez montrer un court mais complet programme qui démontre votre problème, il va être beaucoup plus facile d'expliquer ce qu'il se passe.

Il est difficile de faire ce sujet de la justice, en quelques paragraphes, donc j'ai un article entier à ce sujet, qui nous l'espérons rendre les choses plus évidentes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X