2009-05-22 7 views
3

Lorsque je tente de transmettre l'adresse d'une variable publique comme ceci:Passage adresse de variable publique

ML.Register("Radius", &lBeacons[i].Radius, 0.0f, 200.0f, 10.0f); 

je reçois cette erreur:

error CS0212: You can only take the address of an unfixed expression inside of a fixed statement initializer 

La fonction Registre ressemble à ceci:

public unsafe void Register(string desc, float* val, float minimum, float maximum, float stepsize) 

Balises est une liste. Il tient une classe avec le rayon public.

+2

Je convoque Jon Skeet! Toute la question pointers-references-classes-and-structs-in-csharp est son sujet favori. –

+2

Re votre commentaire "Je veux stocker l'adresse de Radius (et d'autres) dans ML pour les choses futures" - Non! ne fais pas ça! Les objets .NET se déplacent; vous ne pouvez pas compter sur un pointeur en dehors d'un bloc fixe (qui devrait être de courte durée). Passez l'objet Radius (référence) dans ML et mettez à jour les propriétés de l'objet Radius. –

+0

(Je voulais dire objet Beacon) –

Répondre

2

Pourquoi utiliser des pointeurs? Vous pouvez simplement utiliser le mot clé "ref" pour transmettre une référence de la variable.

exemple:

object blah = new object(); 

CallMethod(ref blah); 


public void CallMethod(ref object param) 
{ 

} 
+0

Oui, j'ai oublié la mention que je veux stocker l'adresse de Radius (et d'autres) dans ML pour les choses futures ... Thats pourquoi j'utilise des pointeurs (et ma pensée C++) – JustFogMaxi

+0

Cela pourrait être légèrement à l'OP, parce que maintenant vous passez, par référence, une référence à une copie encadrée de la variable - qui n'est pas la même que de passer une référence à la variable elle-même ... –

+0

Est-ce que vous dites cela parce que j'utilise un type de référence au lieu d'un type de valeur .. désolé confus? – CSharpAtl

7

Est-ce juste pour passer la valeur il pas de sens par référence?

public void Register(string desc, ref float val, float minimum, 
     float maximum, float stepsize) {...} 

Bien sûr, en utilisant des variables publiques (champs) est une mauvaise idée aussi ... cela fonctionnerait comme ceci:

ML.Register("Radius", ref lBeacons[i].Radius, 0.0f, 200.0f, 10.0f); 

Mais il ne travail si vous faites un Radius propriété - alors ne le faites pas. Envisagez de passer la balise (ou similaire) elle-même, ou un autre mécanisme basé sur un objet (ou peut-être basé sur un événement).


quelque chose comme:

ML.Register("Radius", lBeacons[i], 0.0f, 200.0f, 10.0f); 

avec:

private Beacon beacon; 
public void Register(string desc, Beacon beacon, float minimum, 
     float maximum, float stepsize) { 
    this.beacon = beacon; 
} 
void Foo() { 
    beacon.Radius++; // etc 
} 

Nous avons ici une référence à l'objet Beacon, qui ne possède pas les unsafe problèmes de pointeurs. Si vous ne voulez pas exposer le Beacon directement, pensez à utiliser une interface.

+0

ne peut tout simplement pas rivaliser avec un gars avec votre score de rep ... :) – CSharpAtl

+0

Je ne vous offensez pas .... vous donnez de très bonnes réponses concises ...... très complet. – CSharpAtl

+0

Bien sûr, vous pouvez ;-p –

0

Vous pouvez essayer d'utiliser un bloc fixe.

fixed(float *rad = &(lBeacons[i].Radius))) { 
    ML.Register("Radius", rad, 0f, 200f, 10f); 
} 

Je ne pense pas que vous vouliez le faire dans tous les cas. Si ML utilise rad en dehors du bloc fixe, il est susceptible d'échouer. Je pense que vous feriez mieux de repenser votre API.

+0

Je doute que cela fonctionnerait. Vous obtenez l'adresse du type de valeur copié, je pense. – leppie

4

Pour obtenir un pointeur à une variable, utilisez le mot-clé fixe pour l'épingler en place, comme:

fixed(float *radius=&lBeacons[i].Radius) 
{ 
    ML.Register("Radius", radius, 0.0f, 200.0f, 10.0f); 
} 

La méthode se présente placé dans doit être déclarée comme dangereux.

Questions connexes