是否可以更改基本数据类型的默认值?

时间:2009-10-21 23:26:15

标签: c# generics list struct value-type

我最近创建了一个通用矩阵< T>作为List< List< T>>的包装器的类采集。据我所知,这堂课工作得很好。关于T的默认值,我遇到了一个小问题。

我创建了一个Matrix< int>(3,3)的实例,它创建了一个3x3的整数矩阵,默认使用默认值(T)默认为0。我知道值类型(包括基元)默认为0等效,引用类型默认为null。我想知道是否可以更改此默认值,以便如果将值类型传递到Matrix,则会填充5,例如,而不是0。

我尝试创建自己的struct(值类型),但由于无法在结构体中使用无参数构造函数,我找不到从0更改默认值的方法。

我怀疑更改默认值是不可能的,并且在实例化之后我将不得不逐个单元地循环遍历Matrix,但我想在此处询问以防万一之前。

6 个答案:

答案 0 :(得分:3)

 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 :(得分:1)

没有办法像你描述的那样改变默认值。

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

这里有一个msdn article,虽然它没有比不幸的说法更具描述性。

答案 2 :(得分:1)

您可以创建一个封装其值的结构,并仅使用您想要的默认值的偏移量公开它:

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

答案 3 :(得分:0)

好了,因为您已经查看了结构,您可以按如下方式模拟默认值:

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

答案 4 :(得分:0)

我对default(T)的实现的理解是默认情况下,运行时会在应用程序请求时将内存清零,而C#只是分配空间而不会覆盖零。恰好,非数字类型的默认值(例如空引用,false)在内存中表示为零。这可能会导致一些奇怪的行为;例如,即使您从未指定枚举值等于零,default(MyEnumType)也将为零。

答案 5 :(得分:0)

结合Guffa和DougJones的想法,你可以抵消一个属性支持成员。

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