O tipo 'string' deve ser um tipo não nulo para poder usá-lo como parâmetro T no tipo ou método genérico 'System.Nullable <T>'

172

Por que obtenho o erro "O tipo 'string' deve ser um tipo de valor não anulável para usá-lo como parâmetro 'T' no tipo ou método genérico '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; }
      }
    }
}
MiscellaneousUser
fonte
21
Stringjá é anulável.
214122 M.Babcock

Respostas:

204

Use em stringvez de string?em todos os lugares do seu código.

O Nullable<T>tipo requer que T seja um tipo de valor não anulável, por exemplo intou DateTime. Tipos de referência como stringjá podem ser nulos. Não haveria sentido em permitir coisas Nullable<string>assim, pois não é permitido.

Além disso, se você estiver usando o C # 3.0 ou posterior, poderá simplificar seu código usando propriedades implementadas automaticamente :

public class WordAndMeaning
{
    public string Word { get; set; }
    public string Meaning { get; set; }
}
Mark Byers
fonte
1
M.Babcock, quando eu faço m_Word = null, erros, alguma sugestão? Quero poder definir o Word como nulo.
MiscellaneousUser
1
@Misc MiscellaneousUser: Que mensagem de erro você recebe? Você pode postar o arquivo exato que tentou compilar? É difícil adivinhar qual é o seu erro ao ver apenas uma linha do seu código. Quero dizer, pode estar faltando um ponto-e-vírgula ... mas talvez você tenha esquecido de copiá-lo e colá-lo ... Não passa de suposições até você publicar o código que tentou compilar.
Mark Byers
Obrigado pela ajuda, vi esta postagem stackoverflow.com/questions/187406/… e pode ver que o ponto de interrogação é apenas para tipos de valor.
MiscellaneousUser
@ Usuário Diversos: Não é apenas "para tipos de valor". Ele deve ser especificamente um tipo de valor não anulável . Assim como a mensagem de erro diz.
Mark Byers
1
Depois de programar o Swift por um tempo, esse foi o melhor de mim em um projeto em C #.
Albert Bori
52

stringé um tipo de referência, uma classe. Você pode usar apenas Nullable<T>o T?açúcar sintático C # com tipos de valor não anuláveis , como inte Guid.

Em particular, como stringé um tipo de referência, uma expressão do tipo stringjá pode ser nula:

string lookMaNoText = null;
Jon Skeet
fonte
15

System.String (com S maiúsculo) já é anulável, não é necessário declará-lo como tal.

(string? myStr) está errado.

Chagbert
fonte
Faça uma pequena edição na sua resposta, para destacar a importância da letra maiúscula. Eu sou novo em C # e demorei para sempre a obter essa pequena diferença.
precisa
4

Por uma razão muito específica, digite Nullable<int>seu cursor em Nullable e pressione F12 - Os metadados fornecem a razão (observe a restrição de estrutura):

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

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

Joshua Enfield
fonte
4
Observe que isso Nullable<Nullable<int>>não é permitido, embora Nullable<int>seja uma estrutura.
21812 Mark Byers
Isso é interessante. Isso é "codificado" no compilador? Como é restrito a partir de uma estrutura específica (Nullable <Nullable <... >>)? - Edit vejo agora, aparentemente, ele é especial - Erro de compilação ... deve ser um tipo de valor não nulo ....
Joshua Enfield
4

Observe que na próxima versão do C #, que é 8, as respostas não são verdadeiras.

All the reference types are non-nullable by default e você pode realmente fazer o seguinte:

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

Contudo,

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

O importante aqui é mostrar a intenção do seu código. Se a "intenção" é que o tipo de referência possa ser nulo, marque-o, caso contrário, a atribuição de valor nulo a não nulo resultaria em aviso do compilador.

Mais informações

ANewGuyInTown
fonte