Pergunta

Eu tenho uma classe que contém dois métodos como estes:

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

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

No entanto, quando eu compilar minha classe eu recebo dois erros:

  1. O melhor correspondência método sobrecarregado para GetBar (int, string, int) tem alguns argumentos inválidos
  2. O argumento '3': não podem converter de '<null>' para 'int'

Eu acho que entendo por que estou recebendo este erro: o compilador não sabe no momento da compilação que o tipo real do objeto. Alguém pode confirmar se estou correto sobre a causa do erro ou ponto o motivo real?

Mais importante, eu posso projetar meu código dessa maneira? Se assim for, o que eu preciso fazer para corrigir os erros? Minha razão para projetar minha classe desta forma é porque eu não quero duplicar o código no GetBar, em getFoo. Os dois métodos de fazer essencialmente a mesma coisa, exceto um tem um terceiro parâmetro.

Graças.

Foi útil?

Solução

NET, existe um conceito distinto entre tipos de referência e tipos de valor.

Um tipo de referência é um objecto que é atribuído na pilha (Vai ser uma subclasse de System.Object). Tudo o que está na pilha é um ponteiro para este objeto. Por isso, é perfeitamente válida para armazenar um ponteiro nulo.

Um tipo de valor é um objeto que é alocado na pilha, ele vai ser uma subclasse de System.ValueType. Porque um tipo de valor vive na pilha, quando você passa o seu valor para uma função, você passa todo o conteúdo do objeto.

Tipos de valor não pode ser nulo.

A maioria C # tipos primitivos são tipos de valor. String é um tipo especial de primitivo que é na verdade um tipo de referência.

.NET 2.0, MS adicionado a capacidade para incluir um tipo genérico dentro de uma estrutura de modo que ele pode simular um tipo nulo. O que realmente acontece é que o interior lógica do Nullable struct está emulando um nulo para você.

Eles expressaram-lo usando um atalho sintaxe, adicionando um ponto de interrogação para o tipo, por exemplo:

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

etc ...

Se você não gosta do int? sintaxe, você sempre pode usar Nullable

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

Como uma nota lateral, eu prefiro adicionar uma sobrecarga ao fazer o que está fazendo, apenas para tornar o mais agradável sintaxe.

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

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

Outras dicas

Tente fazer o terceiro argumento para a getBar um int anulável.

Assim, a assinatura ficaria assim:

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

Você pode descobrir mais sobre tipos anuláveis ??em .NET aqui aqui .

Int32 é um tipo de valor, o que significa null não é um argumento válido para parâmetros do tipo Int32.

Se você realmente precisa ints anuláveis, use o tipo int?.

Os dois erros que você está vendo são realmente o mesmo erro.

Sunny está correto.
Int32 é um tipo de valor e não pode conter o valor 'null'. Se você precisa passar 'nulo' como um valor de parâmetro, use Nullable vez de Int32 como o tipo de argumento.

Você pode encontrar mais informações em tipos anuláveis ??(C # Guia de programação) no MSDN.

Int32 é um alias para int que é um valor de tipo / não-nulo. Para uma versão anulável dele usar System.Nullable ou simplesmente 'int?'.

Também não se esqueça de converter de volta para um int não nulo:

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

onde o número indica qual o valor que deve assumir se ele é de fato nula.

Int32 não pode ser nulo. Torná-lo um tipo anulável em vez disso:

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

OK, então cinco sete pessoas proposto int? como a solução. Proponho duas outras soluções que pode ser mais apropriado, dependendo da situação;

  • Criar uma sobrecarga do método que só tem dois argumentos, e omitir o null ao chamar:

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

    Embora você provavelmente não quer fazer isso desde que você disse que você queria evitar a duplicação de código.

  • Use default vez de null :

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

    A propósito, este é o mesmo que passar o valor 0.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top