Typ „string” musi być typem niepodlegającym wartości null, aby można go było użyć jako parametru T w typie ogólnym lub metodzie „System.Nullable <T>”

172

Dlaczego pojawia się błąd „Typ„ ciąg znaków ”musi być typem wartości niepodlegającym wartości null, aby można go było użyć jako parametru„ T ”w typie ogólnym lub metodzie„ System.Nullable ”?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using Universe;

namespace Universe
{
    public class clsdictionary
    {
      private string? m_Word = "";
      private string? m_Meaning = "";

      string? Word { 
          get { return m_Word; }
          set { m_Word = value; }
      }

      string? Meaning { 
          get { return m_Meaning; }
          set { m_Meaning = value; }
      }
    }
}
Różne Użytkownik
źródło
21
Stringjest już dopuszczalna wartość null.
M.Babcock,

Odpowiedzi:

204

Użyj stringzamiast string?we wszystkich miejscach w kodzie.

Nullable<T>Typu wymaga T typu wartość nie pustych, na przykład intczy DateTime. Typy odwołań, takie jak stringmogą już mieć wartość null. Nie byłoby sensu pozwalać na takie rzeczy, Nullable<string>więc jest to zabronione.

Ponadto, jeśli używasz języka C # 3.0 lub nowszego, możesz uprościć kod, używając właściwości implementowanych automatycznie :

public class WordAndMeaning
{
    public string Word { get; set; }
    public string Meaning { get; set; }
}
Mark Byers
źródło
1
M.Babcock, kiedy robię m_Word = null, pojawiają się błędy, jakieś sugestie? Chcę mieć możliwość ustawienia programu Word na zero.
Różne Użytkownik
1
@MiscellaneousUser: Jaki komunikat o błędzie otrzymujesz? Czy możesz opublikować dokładny plik, który próbowałeś skompilować? Trudno zgadnąć, jaki jest twój błąd, widząc tylko jedną linię kodu. To znaczy, może być tak, że brakuje ci średnika ... ale może po prostu zapomniałeś go skopiować i wkleić ... To tylko zgadywanie, dopóki nie opublikujesz kodu, który próbowałeś skompilować.
Mark Byers,
Dzięki za pomoc, widziałem ten post stackoverflow.com/questions/187406/ ... i widzę, że znak zapytania dotyczy tylko typów wartości.
Różne Użytkownik
@MiscellaneousUser: Nie chodzi tylko o „typy wartości”. Musi być w szczególności typem wartości niepodlegającym wartości null . Tak jak mówi komunikat o błędzie.
Mark Byers,
1
Heh, po pewnym czasie programowania Swifta, ten dał mi wszystko co najlepsze w projekcie C #.
Albert Bori
52

stringjest typem referencyjnym, klasą. Możesz używać Nullable<T>lub T?C # składniowego cukru tylko z typami wartości niepodlegającymi wartości null, takimi jak intiGuid .

W szczególności, podobnie jak stringtyp referencyjny, wyrażenie typu stringmoże już mieć wartość null:

string lookMaNoText = null;
Jon Skeet
źródło
15

System.String (z dużym S) ma już wartość zerową, nie musisz deklarować jej jako takiej.

(string? myStr) jest źle.

Chagbert
źródło
Niewielka edycja Twojej odpowiedzi, aby podkreślić znaczenie dużej litery. Jestem nowy w C # i zajęło mi to zawsze, aby uzyskać tę małą różnicę.
B - rian
4

Z bardzo konkretnego powodu Type Nullable<int>umieść kursor na Nullable i naciśnij F12 - Metadata podaje powód (zwróć uwagę na ograniczenie struct):

public struct Nullable<T> where T : struct
{
...
}

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

Joshua Enfield
źródło
4
Zauważ jednak, że Nullable<Nullable<int>>jest to niedozwolone, mimo że Nullable<int>jest to struktura.
Mark Byers,
To interesujące. Czy jest to „na stałe zakodowane” w kompilatorze? W jaki sposób jest ograniczony z określonej struktury (Nullable <Nullable <... >>)? - Edycja Widzę teraz najwyraźniej jest wyjątkowy - Błąd kompilacji ... musi być typem wartości niepodlegającym zerowaniu ...
Joshua Enfield
4

Zwróć uwagę, że w nadchodzącej wersji C # 8, odpowiedzi nie są prawdziwe.

All the reference types are non-nullable by default i faktycznie możesz wykonać następujące czynności:

public string? MyNullableString; 
this.MyNullableString = null; //Valid

Jednak,

public string MyNonNullableString; 
this.MyNonNullableString = null; //Not Valid and you'll receive compiler warning. 

Ważne jest tutaj pokazanie intencji twojego kodu. Jeśli „intencją” jest to, że typ referencyjny może mieć wartość null, zaznacz go, aby w przeciwnym razie przypisanie wartości null do wartości nie dopuszczającej wartości null spowodowałoby ostrzeżenie kompilatora.

Więcej informacji

ANewGuyInTown
źródło