2009-02-11 6 views
18

Ist es möglich, den parameterlosen Konstruktor von einem Benutzer in C#hide parameterlosen Konstruktor auf struct

ich sie den Konstruktor immer erzwingen will verstecken mit Parametern verwenden

z.B. diese Position Klasse

public struct Position 
{ 
    private readonly int _xposn; 
    private readonly int _yposn; 

    public int Xposn 
    { 
     get { return _xposn; } 
    } 

    public int Yposn 
    { 
     get { return _yposn; } 
    } 

    public Position(int xposn, int yposn) 
    { 
     _xposn = xposn; 
     _yposn = yposn; 
    }   
} 

ich nur Benutzer wollen eine Position, um neue up der Lage sein, durch die x- und y-Angabe Koordinaten

Allerdings ist der parameterlosen Konstruktor IMMER availiable

ich nicht machen kann es privat . Oder sogar definieren es als öffentliche

habe ich gelesen, das Why can't I define a default constructor for a struct in .NET?

aber es tut wirklich

helfen Wenn dies nicht möglich ist - was der beste Weg ist, zu erkennen, ob die Position I bestanden Bin hat Werte?

Die Überprüfung jedes Eigenschaftsfelds? Gibt es einen schöneren Weg?

dank

Antwort

19

Nein, das geht nicht. Wie du gesagt hast, similar question wurde schon einmal gefragt - und ich dachte, die Antwort war ziemlich klar, dass Sie es nicht tun konnten.

Sie kanncreate a private parameterless constructor for a struct, aber nicht in C#. Aber selbst wenn Sie tun, dass es nicht wirklich helfen wird - weil man leicht um es funktionieren kann:

MyStruct[] tmp = new MyStruct[1]; 
MyStruct gotcha = tmp[0]; 

dass der Standardwert von MyStruct sein wird - die „alle Nullen“ Wert - ohne jemals einen Konstruktor aufrufen .

Sie könnten leicht eine Validate-Methode zu Ihrer Struktur hinzufügen und jedes Mal aufrufen, wenn Sie eine als Parameter erhalten haben.

+3

Ich sehe das als ein Usability-Problem mehr als alles andere. Der Standardkonstruktor könnte ein _valid_ Objekt erzeugen, aber für viele Strukturen ist es nicht das, was der Benutzer will oder erwartet. Trotzdem werden einige Leute diesen Standardkonstruktor verwenden, nur weil es die erste Option ist, die ihre IDE ihnen gibt.Und dann werden sie verwirrende Bugs haben, die durch zeroout-Strukturen verursacht werden, die mit Daten gefüllt sein sollten, oder sie werden Zeit verschwenden, um herauszufinden, warum sie keine Eigenschaften für eine unveränderbare Struktur festlegen können. Aus Sicht des API-Designs wünschte ich, dass es möglich wäre, den Standardkonstruktor zu verbergen. –

+1

+1 @MB. Ein privater Standardkonstruktor würde helfen, selbst wenn ein bestimmter "Dummkopf" das umgehen könnte. Als C++ - Salz halte ich "Private" für einen Hinweis, sich nicht in den Fuß zu schießen, es gibt immer einen Wegweiser mit Zeigern. Und Array-Semantiken können berücksichtigt werden, indem Arrays von solchen Strukturen einfach nicht erzeugt werden. –

+0

@roryapL Korrigiert, danke. –

2

Gut eine Struktur ist buchstäblich eine Erklärung dafür, wie der Speicher sitzen.

Auch wenn Sie ein Objekt verwenden, wird der Objektzeiger deklariert, unabhängig davon, ob er null ist.

Der Grund, warum Sie den Konstruktor nicht verbergen können, ist, weil die Struktur verlangt, dass die CLR sie intern erstellen kann.

Sie könnten diese Struktur in ein Objekt konvertieren, um diese Aufgabe zu erfüllen. Oder verwenden Sie statische Analyse, um sicherzustellen, dass es initialisiert wird, bevor Sie es verwenden?

struct point 
{ 
    int xpos; 
    int ypos; 
} 

Haben Sie ein Google für unveränderliche Objekte, dies scheint, was Sie nach sind. Ich glaube, dass sie versuchen, diese Funktion (aber nicht in C# 4) der Sprache selbst hinzuzufügen, weil es eine allgemeine Anforderung ist. Gibt es hier einen spezifischen Bedarf für eine Struktur?

+0

was meinst du damit? Verwenden Sie statische Analyse, um sicherzustellen, es ist initialisiert Sie meinen, jedes Feld hat einen Wert? – ChrisCa

+0

Sie können ein statisches Analysetool mit einer Regel ausführen, um sicherzustellen, dass jedes Mal, wenn jemand den Typ in seinem Code verwendet, die beiden Werte initialisiert werden. oder Sie könnten eine ausgeklügelte Fußarbeit machen, indem Sie es als Objekt deklarieren, um die Überprüfung durchzuführen, und dann zu einer Struktur im Release-Build wechseln. – Spence

4

Nö kann es nicht verstecken. Structs können den Null-Arg-Konstruktor nicht neu definieren, daher kann seine Sichtbarkeit nicht neu definiert werden.

+0

Nun, .NET ermöglicht es Ihnen, einen benutzerdefinierten parameterlosen Konstruktor zur Verfügung zu stellen - aber Sie können es nicht * direkt * in C# tun, und es hilft sowieso nicht viel, da Sie es leicht umgehen können. –

1

Sie können keine Struktur mit einem privaten, parameterlosen Konstruktor erstellen oder sogar einen Konstruktor ohne Parameter deklarieren. Sie müssten es in eine Klasse ändern. Strukte sind nicht erlaubt, einen parameterlosen Konstruktor zu deklarieren.

Vom Structs Tutorial auf MSDN:

Structs können Konstrukteure erklären, aber sie müssen Parameter übernehmen. Es ist ein Fehler, einen (parameterlosen) Standardkonstruktor für eine Struktur zu deklarieren. Struct-Mitglieder können keine Initialisierer haben. Ein Standardkonstruktor wird immer bereitgestellt, um die Strukturelemente auf ihre Standardwerte zu initialisieren.

Vom C# specification auf MSDN:

11.3 Klasse und Struktur Unterschiede

Structs unterscheiden sich von Klassen in mehreren wichtigen Punkten:

  • Structs sind Werttypen (Abschnitt 11.3.1).
  • Alle Strukturtypen erben implizit aus der Klasse System.ValueType (Abschnitt 11.3.2). Die Zuweisung an eine Variable eines Strukturtyps erzeugt eine Kopie des zugewiesenen Wertes (Abschnitt 11.3.3).
  • Der Standardwert eines struct ist der Wert, der durch alle Werte Typfelder auf ihren Standardwert Einstellung und alle Felder Referenztyp (Abschnitt 11.3.4) auf null. Boxen und Unboxing-Operationen werden verwendet, um konvertieren zwischen einem Strukturtyp und Objekt (Abschnitt 11.3.5).
  • Die Bedeutung davon ist unterschiedlich für Strukturen (Abschnitt 11.3.6).
  • Instanzfelddeklarationen für eine Struktur dürfen variable Initialisierer nicht enthalten (Abschnitt 11.3.7).
  • Eine Struktur darf einen parameterlosen Instanzkonstruktor (Abschnitt 11.3.8) nicht deklarieren.
  • Eine Struktur darf keinen Destruktor deklarieren (Abschnitt 11.3.9).
Verwandte Themen