Pergunta

Eu tenho uma classe contendo várias propriedades, algo como:

public class Update
{
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public string Name { get; set; }
}

Cada instância de Update não tem necessariamente cada propriedade definida e outra parte do sistema precisa saber quais foram definidas e quais não foram.

Uma opção que tenho é criar todos os tipos de valor Nullable e então um null value representaria o conceito de não ser definido.Embora isso funcione, eu realmente não gosto da ideia de ter algumas propriedades explicitamente Nullable (os tipos de valor) e alguns anuláveis ​​em virtude de serem um tipo de referência.A definição da classe ficaria feia e não estou convencido de que uma verificação nula seja semanticamente a melhor abordagem.

Eu poderia criar uma classe muito semelhante a Nullable<T> que não tem qualquer restrição T com um IsSet propriedade.Eu prefiro esta opção do que usar Nullable, mas ainda gostaria de ver se alguém tem uma representação alternativa melhor do que as opções que sugeri.

Foi útil?

Solução

Você realmente deveria seguir o idioma preexistente aqui.Use a nulidade integrada.

Vejo que sua preocupação com a nulidade é diferente para tipos de valor e referência.Sua solução alternativa funcionaria.Mas é apenas uma mudança cosmética que lhe dá pouco ganho.Eu recomendo que você mesmo mude em vez de alterar o código neste caso.Tente se adequar às convenções existentes.

Editar:Às vezes você precisa tornar um valor opcional em código genérico.Neste caso você precisa usar algum tipo de opção personalizada.Por experiência própria, posso dizer que isso é muito desagradável de usar.Não é minha solução preferida.

Outras dicas

Os tipos de referência são anulável, efetivamente - se você usar int?, decimal? e string então cada uma de suas propriedades pode ser nula.

O problema surge se você quiser definir o string valor para uma referência nula - se nulo for efetivamente um valor válido que é definir.

Você certamente poderia escreva um Maybe<T> tipo, mas não tenho certeza se faria isso - eu faria provavelmente basta usar nulo ...além de qualquer outra coisa, será mais familiar para outras pessoas que estão lendo o código e que estão acostumadas com expressões idiomáticas do C#.Apesar de todo o sentimento "anti-nulo" existente (que eu fazer compartilhar em muitas situações) há casos em que é a abordagem mais simples.

Eu realmente não gosto da ideia de ter algumas propriedades anuláveis ​​(os tipos de valor) e alguns não (os tipos de referência)

Os tipos de referência são obviamente anuláveis.

string t = null; //is totally valid

Eu diria que Nullable é exatamente o que você deseja usar para essa finalidade.Você pode envolver os membros com propriedades (como já faz) para que a classe mostre valores normais para o exterior junto com os métodos "está definido" para verificar, se necessário.Mas por dentro eu usaria Nullable.

Para sugerir algo novo...Se você estiver falando apenas de uma classe como Update com um número limitado de membros, eu usaria apenas IsSet.

Mas se você tiver, ou seja,uma série de classes semelhantes com esse comportamento ou muitas propriedades. Eu poderia sugerir que você usasse modelos t4.Você pode, por exemplo, obter propriedades de classe (do tipo ou atributo necessário) conforme descrito neste artigo e gerar código automaticamente com base na lista de propriedades (implementando qualquer design desejado automaticamente)

Eu poderia descrevê-lo melhor se alguém estiver interessado...

A solução aqui para

  • use nullable sempre que null não for uma opção válida
  • use um valor padrão sempre que null for uma opção válida, mas você tiver certeza absoluta de que um determinado valor não ocorrerá
  • use um sinalizador booleano para cada propriedade onde null é um valor válido e você não pode nomear um padrão que nunca será usado.

Exemplos:Quantidade deve ser anulável, pois se for definida seu valor nunca será nulo

O nome deve ser padronizado como "" se o nome puder ser nulo (falta de um nome) e você tiver certeza de que o nome nunca será ""

Um sinalizador, digamos nameSet, deve ser usado se Name tiver um valor nulo e você não conseguir pensar em um valor padrão.Este sinalizador seria falso por padrão e quando você definir o valor de Nome pela primeira vez, o sinalizador também deverá ser definido como verdadeiro.

Se você quiser lidar com todas as suas propriedades da mesma maneira, uma solução seria criar uma classe que conteria um Objeto e um sinalizador booleano.O Object armazenaria o valor da propriedade e o sinalizador armazenaria se a propriedade foi inicializada, mas não gosto disso, porque cria um sinalizador booleano mesmo que não seja necessário.

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