Question

J'ai une classe qui contient deux méthodes comme celles-ci:

public String getFoo(Int32 a)
{
  return getBar(a, "b", null);
}

public String getBar(Int32 a, String b, Int32 c)
{
  //do something
  return "";
}

Cependant, lorsque je compile ma classe, deux erreurs se produisent:

  1. La meilleure correspondance de méthode surchargée pour getBar (int, chaîne, int) contient des arguments non valides
  2. Argument '3': impossible de convertir de '<null>' à 'int'

Je pense comprendre pourquoi je reçois cette erreur: le compilateur ne sait pas au moment de la compilation, quel est le type réel de l'objet? Est-ce que quelqu'un peut confirmer si j'ai raison sur la cause de l'erreur ou indiquer la vraie raison?

Plus important encore, puis-je concevoir mon code de cette façon? Si oui, que dois-je faire pour réparer les erreurs? La raison pour laquelle j'ai conçu ma classe de cette manière est que je ne veux pas dupliquer le code dans getBar, dans getFoo. Les deux méthodes font essentiellement la même chose sauf que l’on prend un troisième paramètre.

Merci.

Était-ce utile?

La solution

Dans .NET, il existe un concept distinct entre les types de référence et les types de valeur.

Un type de référence est un objet alloué sur le tas (ce sera une sous-classe de System.Object). Tout ce qui est sur la pile est un pointeur sur cet objet. Pour cette raison, il est parfaitement valide de stocker un pointeur nul.

Un type de valeur est un objet alloué sur la pile, ce sera une sous-classe de System.ValueType. Étant donné qu'un type de valeur réside dans la pile, lorsque vous transmettez sa valeur à une fonction, vous transmettez l'intégralité du contenu de l'objet.

Les types de valeur ne peuvent pas être null.

La plupart des types primitifs C # sont des types valeur. String est un type spécial de primitive qui est en fait un type de référence.

Dans .NET 2.0, MS a ajouté la possibilité d’enfermer un type générique dans une structure afin qu’il puisse simuler un type nullable. Ce qui se passe réellement, c’est que la logique à l’intérieur de Nullable & Lt; T & Gt; struct émule un null pour vous.

Ils l'ont exprimé à l'aide d'un raccourci de syntaxe en ajoutant un point d'interrogation au type, par exemple:

int? nullableInt = null;
float? nullableFloat = null;

etc ...

Si vous n'aimez pas l'int? syntaxe, vous pouvez toujours utiliser Nullable < SomeType >

public String getBar(Int32 a, String b, Nullable<Int32> c)

En remarque, je préfère ajouter une surcharge lorsque vous faites ce que vous faites, simplement pour rendre la syntaxe plus agréable.

public String getBar(Int32 a, String b)
{
     this.getBar(a,b,null);
}

public String getBar(Int32 a, String b, Nullable<Int32> c)
{
}

Autres conseils

Essayez de transformer le troisième argument en getBar un entier nullable

.

La signature devrait donc ressembler à ceci:

public String getBar(Int32 a, String b, Int32? c)

Pour en savoir plus sur les types nullables dans .NET, ici et ici .

Int32 est un type de valeur, ce qui signifie que null n'est pas un argument valide pour les paramètres de type int?.

Si vous avez vraiment besoin d'ints nullable, utilisez le <=> type.

Les deux erreurs que vous voyez sont en réalité la même erreur.

Sunny est correct.
Int32 est un type de valeur et ne peut pas contenir la valeur 'null'. Si vous devez passer 'null' en tant que valeur de paramètre, utilisez Nullable au lieu de Int32 comme type d'argument.

Vous pouvez trouver plus d'informations à l'adresse Types nullables (C #). Guide de programmation) sur MSDN.

Int32 est un alias pour int, qui est un type value / non-nullable. Pour une version nullable de celui-ci, utilisez System.Nullable ou simplement 'int?'.

N'oubliez pas non plus de reconvertir en un entier non nullable

int? nullable = ...;
int non_nullable = nullable??0; 

où le nombre indique quelle valeur il doit prendre s'il est bien nul.

Int32 ne peut pas être null. Faites-en un type nullable à la place:

public String getBar(Int32 a, String b, Int32? c)
{
    if (c.HasValue)
    {
        ...do something with c.Value...
    }
    return "";
}

OK, donc cinq sept personnes ont proposé int? comme solution. Je propose deux autres solutions qui pourraient être plus appropriées, en fonction de la situation;

  • Créez une surcharge de la méthode ne comportant que deux arguments et omettez le null lors de l'appel:

    public String getFoo(Int32 a)
    {
      return getBar(a, "b", null);
    }
    
    public String getBar(Int32 a, String b)
    {
      //do something else, without the int
    }
    

    Bien que vous ne souhaitiez probablement pas faire cela car vous avez dit vouloir éviter la duplication de code.

  • Utilisez default au lieu de 0 :

    return getBar(a, "b", default(int));
    

    Incidemment, cela revient à transmettre la valeur <=>.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top