2017-08-17 7 views
0

J'ai simplifié le code ci-dessous pour illustrer la question. Un seul objet Page peut avoir des objets N Element, en théorie il pourrait y en avoir des centaines. Afin de rendre le code aussi maintenable que possible, je demande s'il y a un moyen de déclarer chaque Element et de l'initialiser sur la même ligne.Comment puis-je utiliser C# 6 pour raccourcir les déclarations répétées et l'initialisation?

La première tentative que j'ai fait était B, mais cela était ennuyeux/fastidieux parce que je devais déclarer la Element en un seul endroit, puis l'initialiser dans le constructeur dans une partie séparée de la classe. La prochaine tentative, et la méthode que j'utilise actuellement est A. C'est un peu plus de code que B pour chaque Element mais c'est un seul endroit. Un autre avantage (dans ma situation) est que l'objet Element n'est pas réellement créé avant/si nécessaire. L'inconvénient (à mon avis de cette méthode) est que quand il y a 20+ Element propriétés le fichier est vraiment très long et tout est copier/coller.

Je cherche un moyen de déclarer et initialiser chaque Element sur une ligne (et si elle peut être un singleton comme Un qui serait un bonus). C est un exemple de ce que je serais d'accord avec mais ne compile pas réellement pour des raisons évidentes. Existe-t-il un moyen d'abréger B ou de le réécrire d'une manière plus courte et plus claire potentiellement avec certaines des nouvelles fonctionnalités C# 6?


public class Authorization 
{ 
} 

public class Element 
{ 
    private Authorization _authorization; 

    public Element(Authorization authorization) 
    { 
     _authorization = authorization; 
    } 
} 

public class Page 
{ 
    private Authorization _authorization; 

    public Page(Authorization authorization) 
    { 
     _authorization = authorization; 

     ElementTwo = new Element(_authorization); 
    } 

    // A 
    private Element _elementOne; 
    public Element ElementOne => _elementOne ?? (_elementOne = new Element(_authorization)); 

    // B 
    public Element ElementTwo { get; private set; } 

    // C - Ideal 
    // A field initializer cannot reference the non-static field, method, or property 'Page.Authorization' 
    // Cannot access non-static field Authorization in static context 
    public Element ElementThree { get; } = new Element(_authorization); 
} 
+0

Vous voudrez peut-être relire votre article, ce n'est pas très logique. Pouvez-vous modifier pour clarifier? – maccettura

+0

Je ne vois pas où est le problème en combinant B et C, vous pouvez avoir la propriété privée setter et initialiser à la même ligne: 'Element ElementThree {get; ensemble privé; } = new Element (Autorisation); 'Il semble que vous ayez un problème différent puisque vous avez une duplication de code, mais à partir du code fourni, ce n'est pas évident, donc nous ne pouvons pas vous aider. – CrudaLilium

+3

@CrudaLilium Le setter privé n'est pas nécessaire. Votre "solution" échouera à compiler, pour exactement la même raison que le code OP ne compile pas, ce qu'ils ont mentionné dans la question. – Servy

Répondre

2

Vous pouvez utiliser un dictionnaire et une méthode pour cela? Veuillez ne pas me tirer dessus si [CallerMemberName] ne fonctionne pas, je n'ai pas compilé ce code.

public class Page { 

    private readonly Authorization _auth; 
    private readonly IDictionary<string, Element> _elements = new Dictionary<string, Element>(); 

    public Element ElementOne => GetOrCreateElement(); 
    public Element ElementTwo => GetOrCreateElement(); 
    public Element ElementThree => GetOrCreateElement(); 

    public Page(Authorization auth) { 
    _auth = auth; 
    } 

    private Element GetOrCreateElement([CallerMemberName] string name = null) { 
    if(_elements.TryGetValue(name, out var returnElement)) 
     return returnElement; 
    var element = new Element(_auth); 
    _elements.Add(name, element); 
    return element; 
    } 

}