É possível alterar o valor padrão de um tipo de dados primitivo?
-
05-07-2019 - |
Pergunta
Recentemente, criei uma matriz genéricau003CT> classe que atua como um invólucro em torno de uma lista u003CListu003CT> > coleção. Até onde eu sei, esta aula está funcionando perfeitamente. Estou enfrentando um pequeno problema, mas com relação aos valores padrão dos T's.
Eu crio uma instância de matrizu003Cint> (3, 3), que cria uma matriz 3x3 de INTs, todos padrão para 0 usando o padrão (t). Eu sei que os tipos de valor (que incluem primitivos) são inadimplentes para um 0 equivalente e os tipos de referência padrão para nulo. Eu queria saber se era possível alterar esse valor padrão para que, se um tipo de valor for passado para a matriz, ela seria preenchida com 5, por exemplo, em vez de 0.
Tentei criar minha própria estrutura (tipo de valor), mas devido a não poder usar construtores sem parâmetros dentro de estruturas, não consigo encontrar uma maneira de alterar o valor padrão de 0.
Suspeito que a alteração do valor padrão não seja possível, e terei que percorrer a célula da célula matricial depois de ter sido instanciada, mas eu queria perguntar aqui apenas antes de fazer isso.
Solução
public Matrix(int width, int height) : this(width, height, default(T)) {}
public Matrix(int width, int height, T defaultValue)
{
List<T> rows = new List<T>(height);
for (int i = 0; i < height; i++)
{
List<T> columns = new List<T>(width);
for (int j = 0; j < width; j++)
{ columns.Add(defaultValue); }
rows.Add(columns);
}
// store `rows` wherever you are storing it internally.
}
Mas como Joseph diz, não há como definir o que default(T)
avalia para.
Outras dicas
Não há como alterar o valor padrão como como você está descrevendo.
var someInt = default(int); //this will always be 0, you can't change it
var someReference = default(SomeClass); //this will always be null
Aqui está um Artigo do MSDN nele, embora não seja muito mais descritivo do que o que já foi dito, infelizmente.
Você pode fazer uma estrutura que encapsula seu valor e apenas o expõe com um deslocamento do valor padrão que você deseja:
public struct DefaultFiveInteger {
private int _value;
public DefaultFiveInteger(int value) {
_value = x - 5;
}
public static implicit operator int(DefaultFiveInteger x) {
return x._value + 5;
}
public static implicit operator DefaultFiveInteger(int x) {
return new DefaultFiveInteger(x);
}
}
Agora você pode declarar uma variável que é inicializada para o valor padrão (0) e retornará o valor com o deslocamento:
DefaultFiveInteger x;
Console.Write(x);
Resultado:
5
Bem, já que você já está olhando para estruturas, você pode simular um valor padrão da seguinte maneira:
public struct MyInt
{
private int _defaultInt;
public int DefaultInt
{
get
{
if (_defaultInt == 0)
return 5;
else
return _defaultInt;
}
set
{
_defaultInt = value;
}
}
}
Minha compreensão da implementação de default(T)
é que o tempo de execução, por padrão, zeros sai da memória como o aplicativo solicita e c# apenas aloca o espaço sem nunca substituir os zeros. Acontece que os valores padrão de tipos não numéricos (por exemplo, a referência nula, falsa) são representados como zeros na memória. Isso pode levar a algum comportamento estranho; por exemplo, default(MyEnumType)
Será zero, mesmo que você nunca especifique um valor de enum ser igual a zero.
Combinando idéias de Gufffa e Dougjones, você pode compensar um membro do apoio de propriedades.
public struct MyInt
{
private const int INT_DEFAULT = 5;
private int _defaultInt;
public int DefaultInt
{
get { return _defaultInt + INT_DEFAULT; }
set { _defaultInt = value - INT_DEFAULT; }
}
}