Question

Selon vous, quelle valeur les paramètres nommés et par défaut ajouteront dans C#.Net 4.0 ?

Quelle serait une bonne utilisation de ceux-ci (qui n'a pas déjà été réalisée avec la surcharge et la substitution) ?

Était-ce utile?

La solution

Cela peut simplifier les constructeurs, en particulier pour les types immuables (qui sont importants pour le threading) - voir ici pour une discussion complète.Pas aussi sympa que ça devrait être peut-être, mais c'est mieux que d'avoir beaucoup de surcharges.Vous ne pouvez évidemment pas utiliser d'initialiseurs d'objet avec des objets immuables, donc l'habituel :

new Foo {Id = 25, Name = "Fred"}

n'est pas disponible ;Je me contenterai de :

new Foo (Id: 25, Name: "Fred")

Cela peut être étendu à l'idée générale de simplification des surcharges, mais en la plupart Dans certains cas, je préférerais les surcharges qui annoncent les combinaisons légales.Les constructeurs sont un peu différents, IMO, puisque vous définissez simplement (généralement) l'état initial.

Le côté COM est également important pour beaucoup de gens, mais je n'utilise tout simplement pas beaucoup d'interopérabilité COM - donc ce n'est pas le cas. comme important pour moi.


Modifier les commentaires ;pourquoi n'ont-ils pas simplement utilisé la même syntaxe que celle utilisée par les attributs ?Simple - cela peut être ambigu avec d'autres membres/variables (ce qui n'est pas un problème avec les attributs) ;prenons l'exemple :

[XmlElement("foo", Namespace = "bar")]

qui utilise un paramètre régulier (au ctor, "foo") et une affectation nommée.Supposons donc que nous utilisions ceci pour les arguments nommés réguliers :

SomeMethod("foo", SecondArg = "bar");

(qui pourrait aussi être un constructeur ;J'ai utilisé une méthode pour plus de simplicité)

Maintenant...et si nous avions une variable ou une propriété appelée SecondArg?Cela serait ambigu entre l'utilisation SecondArg comme argument nommé pour SomeMethod, et attribuer "bar" à SecondArg, et en passant "bar" comme argument régulier.

Pour illustrer, c'est légal en C# 3.0 :

    static void SomeMethod(string x, string y) { }
    static void Main()
    {
        string SecondArg;
        SomeMethod("foo", SecondArg = "bar");
    }

Évidemment, SecondArg peut être une propriété, un champ, une variable, etc...

La syntaxe alternative n'a pas cette ambiguïté.


Edit - cette section par 280Z28 :Désolé d'avoir ajouté ceci ici, mais ce n'est pas vraiment une réponse unique et c'est trop long pour les commentaires et inclut le code.Vous avez fait allusion à l'ambiguïté, mais votre exemple n'a pas mis en évidence le cas décisif.Je pense que l'exemple que vous avez donné met en évidence quelque chose qui pourrait prêter à confusion, mais les exigences requises {} autour des initialiseurs d'objets évite une ambiguïté syntaxique sous-jacente.Mon explication pour le code suivant est intégrée en tant que commentaire de bloc multiligne.

[AttributeUsage(AttributeTargets.Class)]
public sealed class SomeAttribute : Attribute
{
    public SomeAttribute() { }

    public SomeAttribute(int SomeVariable)
    {
        this.SomeVariable = SomeVariable;
    }

    public int SomeVariable
    {
        get;
        set;
    }
}

/* Here's the true ambiguity: When you add an attribute, and only in this case
 * there would be no way without a new syntax to use named arguments with attributes.
 * This is a particular problem because attributes are a prime candidate for
 * constructor simplification for immutable data types.
 */

// This calls the constructor with 1 arg
[Some(SomeVariable: 3)]
// This calls the constructor with 0 args, followed by setting a property
[Some(SomeVariable = 3)]
public class SomeClass
{
}

Autres conseils

Il vous aidera à esquiver le problème de fournir une API décente pour travailler avec des applications de bureau! :)

Certaines parties de l'API Bureau sont d'accord, mais il y a des cas de pointe qui ont été clairement conçues pour une utilisation d'une langue avec des paramètres facultatifs / nommés. Voilà pourquoi C # doit les avoir.

Les paramètres facultatifs permettent également d'éviter le problème où les classes fournissent des dizaines de méthodes qui ne sont que des variations sur les arguments acceptés.

Considérez la classe d'exception. Au lieu d'un constructeur avec des arguments optionnels, il dispose de quatre constructeurs pour chaque combinaison de « a un message » et « a l'exception interne ». C'est bien, mais maintenant considérer ce qui se passe si vous fournissez une valeur nulle à un constructeur de prendre un innerException? Est-il agir exactement comme le constructeur avec sans paramètre innerException, sortof comme le constructeur sans paramètre innerException, ou faut-il lancer une exception de référence null?

Un seul constructeur avec 2 paramètres optionnels aurait rendu plus évident que le passage d'un innerException nul équivaut à ne pas inclure du tout. Un endroit parfait pour les arguments par défaut.

Aussi, ne pas oublier que maintenant chaque classe dérivée d'exception doit également inclure 4 constructeurs, ce qui est embêtant inutile.

Il fera COM Interop beaucoup plus facile.

Jusqu'à C # 4 VB.Net était une bien meilleure langue pour Interop. Sans défaut vous avez des listes massives de paramètres ref factices en C #.

Brevity de code est celui évident que vient à l'esprit. Pourquoi définir plusieurs quand vous pouvez surcharges définir une fonction. En outre, bien que, si vous avez deux paramètres typés de façon identique, il est pas toujours possible de construire l'ensemble des surcharges vous pourriez avoir besoin.

En outre cela ne compile pas:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute(object a = null)
    {

    }
}


class Test
{
    [My] // [My(a: "asd")]
    int prop1 { get; set; }
}

alors que ce fait:

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
sealed class MyAttribute : Attribute
{
    public MyAttribute()
    {

    }

    public object a { get; set; }
}

class Test
{
    [My] // [My(a=null)]
    int prop1 { get; set; }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top