2009-05-11 29 views
6

Wenn ich eine private Variable habe, für die ich eine interne Validierung haben möchte, und ich möchte diese Validierung an einem Ort behalten, lege ich sie hinter einen Getter/Setter und Greifen Sie nur auf diesen Getter/Setter zu. Das ist nützlich, wenn es um öffentliche Eigenschaften geht, weil der andere Code nicht auf die private Variable zugreifen kann, aber wenn ich mit einem Objekt innerhalb der Klasse selbst zu tun habe, gibt es irgendeine Möglichkeit, den Getter/Setter zu erzwingen?force get/set Zugriff auf private Variablen für private Eigenschaften

private int _eyeOrientation; 

    private int eyeOrientation 
    { 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     if (value < 0) 
     { 
      _eyeOrientation = 0; 
     } 
     else 
     { 
      _eyeOrientation = value % 360; 
     } 
    } 
    } 

Das Problem hierbei ist, dass die anderen Funktionen in der Klasse versehentlich

_eyeOrientation = -1;

, die das Programm in eine tizzy ändern können werfen würde. Gibt es eine Möglichkeit, um einen Compilerfehler zu werfen?

+7

Es ist ein trauriger Tag, wenn Programmierer nicht mehr andere Funktionen innerhalb der gleichen Klasse vertrauen können:) – codeulike

Antwort

10

Klingt, als ob Sie einen Winkeltyp benötigen.

// Non mutable Angle class with a normalized, integer angle-value 
public struct Angle 
{ 
    public Angle(int value) 
    { 
    Value = value; 
    } 

    private angle; 
    public Value 
    { 
    get { return angle; } 
    private set { angle = Normalize(value); } 
    } 

    public static int Normalize(int value) 
    { 
    if (value < 0) return 360 - (value % 360); 
    return value % 360; 
    } 
} 

public class SomeClass 
{ 
    public Angle EyeOrientation { get; set; } 
} 

Wenn Sie eine bestimmte Art von Wert, wie Winkel, Geld, Gewicht oder was auch immer, es ist immer eine gute Praxis eine eigene Art zu machen, auch wenn der Wert selbst in einem int, dezimal gespeichert usw. Dieser Typ macht Ihre Schnittstellen übersichtlicher und typsicher. Es ist nicht dasselbe, wenn Sie einen Winkel oder einen Integer-Wert als Argument einer Methode erwarten.

4

Sie könnten es möglicherweise in einer geschachtelten Klasse definieren.

public class NeedsEye 
{ 

    Eye _eye = new Eye(); 

    public NeedsEye() 
    { 
     // now, here, any access to the property must be made through the 
     // _eye variable. The Eye class has access to any of the properties 
     // and members of the NeedsEye class, but the NeedsEye class has not 
     // any access to members of the Eye class. 
    } 

    private class Eye 
    { 
     private int _orientation; 

     public int Orientation 
     { 
      get { return _orientation; } 

      if (value < 0) 
      { 
       _eyeOrientation = 0; 
      } 
      else 
      { 
       _eyeOrientation = value % 360; 
      }  
     } 
    } 
} 
1

Einfach Ihre privaten Attribut und öffentlichen Getter/Setter in eine private Klasse.

Dann können nur Getter und Setter auf das private Attribut zugreifen.

Es ist Overkill, würde aber funktionieren. :)

9

Im Allgemeinen sollten Sie sich nicht darum kümmern. Klassenmitglieder können die Eigenschaften weiterhin verwenden, wenn Sie die Überprüfung nicht in der Klasse selbst vornehmen möchten.

Wenn Ihre Klasse so groß wird, dass Sie Methoden innerhalb der Klasse nicht mehr vertrauen, würde ich denken, dass es an der Zeit ist, Refactoring zu beginnen und dies in kleinere Klassen zu gliedern, die einfacher zu managen sind.

+0

arbeite ich an einem persönlichen Projekt, bei dem ich versuche, den Zugang möglichst streng zu sein. Nur um zu sehen, ob es möglich ist, alle Ihre Objekte NUR durch die Objekte zugänglich zu machen, die sie brauchen. Sie brauchen diese nicht, wenn Sie sich an gute Programmierpraktiken halten, aber ich war neugierig, ob es möglich ist. – DevinB

1

Je nach Tools, die Sie in der Durchsetzung einer Codierung Konvention nicht, die direkten Zugang zu einem privaten Element außerhalb eines get aussehen könnte/set

Könnte etwas mehr Arbeit, aber Sie müssen nicht eine Reihe von Wrapper erstellen Klassen.

3

Sie können das Feld als veraltet markieren, damit der Compiler eine Warnung generiert, wenn Sie versuchen, darauf zuzugreifen, und dann suppress that warning für die Eigenschaft Getter/Setter.

Die Warncodes, die Sie unterdrücken müssen, lauten CS0612 for the plain Obsolete attribute und CS0618 if the attribute has a custom message.

Im Allgemeinen würde ich dies ein bisschen wie ein Hack und versuchen, es zu vermeiden, wenn möglich. Eine bessere Lösung wäre, den Code angemessen zu kommentieren und Ihre Mitentwickler so zu schulen, dass sie das Richtige tun.

[Obsolete("Please use the EyeOrientation property instead.")] 
private int _eyeOrientation; 

public int EyeOrientation 
{ 
    #pragma warning disable 612, 618 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     _eyeOrientation = (value > 0) ? value % 360 : 0; 
    } 
    #pragma warning restore 612, 618 
} 
+1

(+1) Das ist eine geniale Rundum-Lösung – DevinB

+0

Es ist eine nette Idee, aber ich würde es nicht auf 0 setzen, weil ein negativer Winkel zu einem positiven normalisiert werden könnte, z. -10 ° == 350 °. –

+0

@Stefan, stimme ich zu. Ich habe nur die Funktionalität des Beispielcodes in der Frage dupliziert. – LukeH

Verwandte Themen