我最近创建了一个通用矩阵< T>作为List< List< T>>的包装器的类采集。据我所知,这堂课工作得很好。关于T的默认值,我遇到了一个小问题。
我创建了一个Matrix< int>(3,3)的实例,它创建了一个3x3的整数矩阵,默认使用默认值(T)默认为0。我知道值类型(包括基元)默认为0等效,引用类型默认为null。我想知道是否可以更改此默认值,以便如果将值类型传递到Matrix,则会填充5,例如,而不是0。
我尝试创建自己的struct(值类型),但由于无法在结构体中使用无参数构造函数,我找不到从0更改默认值的方法。
我怀疑更改默认值是不可能的,并且在实例化之后我将不得不逐个单元地循环遍历Matrix,但我想在此处询问以防万一之前。
答案 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; }
}
}