Можно ли изменить значение по умолчанию для примитивного типа данных? - PullRequest
2 голосов
/ 22 октября 2009

Недавно я создал универсальный класс Matrix , который действует как оболочка для коллекции List >. Насколько я могу судить, этот класс работает отлично. Я столкнулся с небольшой проблемой, хотя в отношении значений по умолчанию T.

Я создаю экземпляр Matrix (3, 3), который создает матрицу 3x3 целых чисел, все по умолчанию равны 0, используя default (T). Я знаю, что типы значений (которые включают в себя примитивы) по умолчанию равны 0, а ссылочные типы по умолчанию равны нулю. Мне было интересно, можно ли было изменить это значение по умолчанию так, чтобы, если тип значения передавался в матрицу, он заполнялся, например, цифрами 5 вместо 0.

Я попытался создать свою собственную структуру (тип значения), но из-за невозможности использовать конструкторы без параметров внутри структур, я не могу найти способ изменить значение по умолчанию с 0.

Я подозреваю, что изменение значения по умолчанию невозможно, и мне придется циклически проходить по матрице ячейка за ячейкой после ее создания, но я хотел бы спросить здесь на всякий случай, прежде чем я это сделаю.

Ответы [ 6 ]

3 голосов
/ 22 октября 2009
 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.
 }

Но, как говорит Джозеф, нет способа установить то, что default(T) оценивает.

1 голос
/ 22 октября 2009

Вы можете создать структуру, которая инкапсулирует ее значение и предоставляет только смещение требуемого значения по умолчанию:

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);
   }

}

Теперь вы можете объявить переменную, которая инициализирована значением по умолчанию (0), и она вернет значение со смещением:

DefaultFiveInteger x;
Console.Write(x);

Выход:

5
1 голос
/ 22 октября 2009

Нет способа изменить значение по умолчанию, например, как вы описываете.

var someInt = default(int); //this will always be 0, you can't change it
var someReference = default(SomeClass); //this will always be null

Вот статья msdn , хотя она не намного более наглядна, чем, к сожалению, уже сказано.

0 голосов
/ 17 сентября 2011

Комбинируя идеи Гуффы и Дугджонса, вы можете компенсировать элемент поддержки свойств.

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; }
    }
}
0 голосов
/ 22 октября 2009

Мое понимание реализации default(T) состоит в том, что среда выполнения по умолчанию обнуляет память по мере того, как приложение ее запрашивает, а C # просто выделяет пространство, не перезаписывая нули. Так уж получилось, что значения по умолчанию для нечисловых типов (например, нулевая ссылка, ложь) представлены в памяти как нули. Это может привести к странному поведению; например, default(MyEnumType) будет нулевым, даже если вы никогда не указывали значение enum равным нулю.

0 голосов
/ 22 октября 2009

Ну, так как вы уже просматриваете структуры, вы можете смоделировать значение по умолчанию следующим образом:

public struct MyInt
{
    private int _defaultInt;
    public int DefaultInt
    {
        get
        {
            if (_defaultInt == 0)
                return 5;
            else
                return _defaultInt;
        }
        set
        {
            _defaultInt = value;
        }
    }
}
...