2010-10-17 7 views
1

J'ai le bit de code suivant:problème avec le constructeur de struct (compilateur hurle que je n'initialise pas entièrement toutes les auto-propriétés de la struct)

public struct Interval 
{ 
    public double Min { get; set; } 
    public double Max { get; set; } 

    public Interval(double min = double.MinValue, double max = double.MaxValue) 
    { 
     Min = min; 
     Max = max; 
    } 
} 

Le compilateur se plaint que

Le champ de support pour la propriété implémentée automatiquement doit être entièrement affecté avant que le contrôle ne soit renvoyé à l'appelant. Envisagez d'appeler le constructeur par défaut à partir d'un constructeur initialiseur.

Ce qui est quelque chose que je ne comprends pas, puisque mon constructeur initialise complètement les valeurs de cette structure. N'est-ce pas?

Répondre

2

Heed le message d'erreur et ajoutez un appel au constructeur par défaut comme ceci:

public Interval(
    double min = double.MinValue, 
    double max = double.MaxValue 
) 
    : this() { 
     Min = min; 
     Max = max; 
} 

Le problème est que comme écrit les champs d'accompagnement ne sont pas initialisé; cela rend le compilateur très malheureux. Cependant, le constructeur par défaut sans paramètre initialisera ces champs pour vous, ce qui explique pourquoi le problème disparaît lorsque nous enchaînons un appel à ce constructeur.

+4

Wow, c'est une indentation confuse. Cela donne l'impression que le corps est associé à 'this()' (ce n'est pas le cas). –

+1

Oh Seigneur, downvoting réponses correctes à cause de l'indentation non standard? Quel étourdi. –

+0

@Ben Voigt: Vraiment? Quiconque connaît la syntaxe de chaînage des constructeurs C#, je pense, lirait correctement ceci. Le fait de mettre l'accolade sur la ligne suivante change-t-il vraiment quelque chose? – jason

7

Votre constructeur tente de définir propriétés - qui ne peut pas faire jusqu'à ce qu'il sait que tous les champs ont été initialisées. (Vous ne pouvez pas appeler de méthodes d'instance ou accéder aux propriétés tant que tous les champs de la structure ne sont pas assignés.) C'est une bizarrerie qui se manifeste lorsque vous utilisez des propriétés implémentées automatiquement: vous avez d'autres champs que la propriété, mais vous ne pouvez pas utiliser la propriété avant d'attribuer une valeur au champ! La solution est simple - il suffit d'ajouter un appel au constructeur parameterless:

public Interval(double min = double.MinValue, double max = double.MaxValue) 
    : this() 
{ 
    Min = min; 
    Max = max; 
} 

Cela fonctionne parce que le constructeur attribue parameterless les valeurs par défaut à tous les champs, après quoi vous pouvez utiliser les propriétés sans aucun problème.

Cependant, je recommande de ne pas utiliser de structures mutables en premier lieu.

+0

Maintenant que j'y pense, la raison pour laquelle ils ont été structs était que je les avais réellement immuables. –

+1

@devoured elysium: Vous pouvez les rendre immuables comme des classes aussi, bien sûr :) –

-2

Il compile très bien pour moi: http://ideone.com/mgBpt

Quelle version de C# et compilateur utilisez-vous?

+1

Cela échoue pour moi avec Mono et le compilateur MS - et il * devrait * échouer. –

0

Ajouter: cette() au cteur:

public Interval(...args...) : this() { 
    ... Code ... 
} 
0

Je viens d'écrire ces quelques jours en arrière.

http://www.abhisheksur.com/2010/10/hidden-facts-on-c-constructor-in.html

Si vous écrivez un constructeur pour votre structure, vous devez initialiser chaque membre de votre struct avant de revenir du constructeur. Les champs de sauvegarde peuvent créer un problème avec votre code, vous pouvez le réparer en utilisant l'appel au constructeur par défaut.

this()