Frage

Ich habe eine Klasse mit zwei Methoden wie diese:

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

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

Aber wenn ich kompilieren meiner Klasse bekomme ich zwei Fehlermeldungen:

  1. Die beste überladene Methode match für getBar(int,string,int) hat einige ungültige Argumente
  2. Argument '3':cannot convert from '<null>'to 'int'

Ich glaube, ich verstehe, warum ich bin immer diese Fehlermeldung:der compiler weiß nicht, zu der Zeit der Zusammenstellung, was den tatsächlichen Typ des Objekts ist.Kann jemand bestätigen, ob ich richtig bin über die Ursache des Fehlers oder auf den Punkt der wirkliche Grund?

Noch wichtiger ist, kann ich das design für meine code-auf diese Weise?Wenn ja, was muss ich tun, um die Fehler zu beheben?Mein Grund für die Gestaltung meiner Klasse diese Weise ist, weil ich nicht wollen, duplizieren Sie den code in getBar, in getFoo.Die beiden Methoden führen im wesentlichen die gleiche Sache, außer man einen Dritten parameter.

Vielen Dank.

War es hilfreich?

Lösung

In .NET gibt es ein besonderes Konzept zwischen Referenztypen und Werttypen.

Ein Referenztyp ist ein Objekt, das auf dem Heap zugeordnet wird (es wird eine Unterklasse von System.Object sein). Alles, was auf dem Stapel ist ein Zeiger auf dieses Objekt. Aus diesem Grunde ist es durchaus möglich, einen Null-Zeiger zu speichern.

Ein Werttyp ist ein Objekt, das auf dem Stapel zugeordnet ist, wird es eine Unterklasse von System.ValueType sein. Da ein Werttyp auf dem Stapel lebt, wenn Sie den Wert auf eine Funktion übergeben, können Sie den gesamten Inhalt des Objekts übergeben.

Werttypen können nicht null sein.

Die meisten C # primitive Typen sind Werttypen. String ist eine spezielle Art von primitiven, die tatsächlich ein Referenztyp ist.

In .NET 2.0, hinzugefügt MS die Möglichkeit, eine generische Art innerhalb einer Struktur zu umschließen, so dass es ein Nullable Type simulieren könnte. Was wirklich passiert ist, dass die Logik innerhalb des Nullable struct eine null für Sie emuliert.

Sie drücken sie eine Syntax Kürzel durch ein Fragezeichen auf den Typen hinzufügen, zum Beispiel:

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

etc ...

Wenn Sie nicht über die int gefallen hat? Syntax, können Sie immer Nullable verwenden

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

Als Randbemerkung, ziehe ich eine Überlastung hinzuzufügen, wenn das tun, was Sie tun, nur die Syntax schöner zu machen.

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

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

Andere Tipps

Versuchen Sie das dritte Argument der getBar ein Nullable-int zu machen.

So würde die Signatur wie folgt aussehen:

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

Sie können mehr über Nullable Types in .NET erfahren Sie hier und hier .

Int32 ist ein Werttyp, der null bedeutet nicht ein gültiges Argument für Parameter vom Typ Int32.

Wenn Sie wirklich nullable Ints benötigen, verwenden Sie die int? Art.

Die beiden Fehler, die Sie sehen, sind eigentlich die gleichen Fehler.

Sunny ist richtig.
Int32 ist ein Werttyp und kann nicht den Wert ‚Null‘ halten. Wenn Sie ‚null‘ als Parameterwert zu übergeben, verwendet Nullable statt Int32 als Argument Typ.

Sie finden weitere Informationen finden Sie unter Nullable Types (C # Programming Guide) auf MSDN.

Int32 ist ein alias für int, die einen Wert/non-nullable-Typ.Für eine null-version des Systems verwenden.Null-Werte zulässt oder einfach 'int?'.

Vergessen Sie auch nicht zurück konvertieren zum einem nicht-nullable int:

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

wo die Zahl gibt an, welchen Wert Sie annehmen sollen, wenn es ist in der Tat null.

Int32 kann nicht null sein. Machen Sie es ein Nullable Type statt:

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

OK, also fünf sieben Personen int? als Lösung vorgeschlagen. Ich schlage vor, zwei andere Lösungen, die Macht besser geeignet sein, abhängig von der Situation;

  • Erstellen Sie eine Überlastung der Methode, die nur zwei Argumente hat, und lassen Sie die null beim Aufruf:

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

    Auch wenn Sie wahrscheinlich nicht wollen, dies zu tun, da Sie erklärt, dass Sie wollten Code-Duplizierung vermeiden.

  • Verwenden default statt null :

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

    Dies ist übrigens die gleiche wie der Wert 0 geben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top