Question

Pour un peu d’arrière-plan, j’ai une application qui tourne en boucle et coche à chaque fois qu’elle appelle une méthode Tick. Il y a un tas de classes qui étendent une classe de base et qui ont toutes leurs propres méthodes de ticks et qui sont ajoutées à une chaîne de dépendance. Ainsi, lorsque la classe A est appelée et que sa chaîne contient des occurrences de B et C, B.Tick est appelée , suivi de C.Tick, puis enfin A.Tick.

Donc, dans le pseudo-code, ma classe ressemble à ceci:

public class A : Super
Super b;
Super c;
ArrayList one;
ArrayList two;

tick(){
    one.Add(b.LastValue);
    two.Add(c.LastValue);
            ... do something with one and two ...
}

A(){
    b = new B(some other array list);
    c = new C(ref one);
}

B fonctionne bien et obtient toujours la valeur correcte. Le problème est que je suppose que vous ne pouvez pas stocker une référence à une autre variable dans une classe, donc quand je fais un nouveau C (ref one); et le constructeur pour C définit une variable de classe sur un, plus tard, une fois mise à jour en A, on dirait que C ne sait plus qu'il est toujours censé pointer vers un (qui est maintenant mis à jour) et qu'il est simplement vide (comme à l'origine était à l'intérieur du constructeur). Une idée sur la façon de réaliser ce que je cherche à faire, sans avoir à utiliser de pointeurs C # et de code non sécurisé? Merci, j'espère que cela a du sens:)

Modifier: Apparemment, les gens ne peuvent pas répondre à des questions avec un pseudo-code déroutant qui n’a aucun rapport avec la question, alors la modification a été étendue:

Éditer 2: classe C

...
ArrayList local;
...
C(ref ArrayList one){
    local = one;
}

Tick(){
   LastValue = local[0] + 5; //not actual formula, just shows trying to use a referenced variable 
}
Était-ce utile?

La solution

Étant donné que one est une liste de tableaux, vous pouvez uniquement le transmettre en tant que référence. Vous le transmettez apparemment en tant que référence à une référence au constructeur. Vous n’avez peut-être pas besoin de ref .

Mais s'il vous plaît, montrez une idée plus complète de ce que vous essayez d'accomplir.

Modifier:

Après avoir vu votre classe C, le ref n'est pas nécessaire. c partagera l'instance de ArrayList qui appelle A one .

Cela semble se résumer au problème du type référence / type de valeur général dans .NET. Pour résumer:

  • les occurrences d’objets n’ont pas de nom et ne peuvent pas (physiquement) être passées en paramètre.
  • vous accédez toujours à une instance via une référence. Dans votre code, one (2x), deux , local sont toutes des références à des instances Arraylist.
  • les références elles-mêmes se comportent comme des types de valeur, c.-à-d. que l’affectation signifie la copie.

Pour en savoir plus sur les types de référence / types de valeur, recherchez "sémantique de copie" et évitez les publications commençant par "types de valeurs existant dans la pile".

Autres conseils

Rien ne vous empêche de le faire. Que ce soit ou non une bonne idée est une autre question cependant. En général, je vous recommanderais d'essayer d'éviter de changer d'état entre les appels de méthode si vous pouvez l'éviter. Bien sûr, l’expression clé qui existe est "si vous pouvez l’éviter". : -)

  

vous ne pouvez pas stocker une référence à une autre variable dans une classe

Vous pouvez, les gens le font tout le temps. Attribuez-le simplement à un champ (privé).

  

alors quand je fais un nouveau C (ref one); [snip /] plus tard après avoir été mis à jour dans A c'est comme si C ne savait plus qu'il était toujours supposé pointer vers un

En fait, il le sait, mais vous devez attribuer one à un champ membre. L'affectation à des objets n'est rien de plus que la définition d'une référence à l'objet. Changer l'objet, les change partout où vous l'avez assigné:

class A
{
    public string Hello { get; set; }
}

class C
{
    private A myA;
    public C(A a) { myA = a; }
    public A GetMyA() { return myA; }
}

// somewhere else:
A someA = new A();
someA.Hello = "Hello World";
C someC = new C(someA);
someA.Hello = "Other World";
Console.WriteLine(someC.GetMyA().Hello);

// this will print "Other World" and not "Hello World" as you suggest

PS: puisque vous publiez du pseudocode, j'espère que cela ne vous dérange pas que je simplifie un peu. Si j'ai mal compris votre question, veuillez ne pas en tenir compte (et peut-être clarifier, si possible).

PPS: en relisant votre code (modifié) tout en essayant de comprendre le problème, rien ne semble empêcher le C de votre code de conserver un membre avec une référence. to A et l'appel de a.Add reflétera évidemment la variable membre dans c . En effet, pas besoin de ref ici.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top