プリミティブデータ型のデフォルト値を変更することは可能ですか?
-
05-07-2019 - |
質問
最近、汎用Matrix <!> lt; T <!> gt;を作成しました。 List <!> lt; List <!> lt; T <!> gt; <!> gt;のラッパーとして機能するクラス。コレクション。私の知る限り、このクラスは完璧に機能しています。 Tのデフォルト値に関してはわずかな問題に直面しています。
Matrix <!> lt; int <!> gt;(3、3)のインスタンスを作成し、intの3x3マトリックスを作成します。デフォルトはすべてdefault(T)を使用して0に設定されます。値型(プリミティブを含む)のデフォルトは0に相当し、参照型のデフォルトはnullであることを知っています。このデフォルト値を変更して、値の型がマトリックスに渡されると、0ではなく5などが入力されるようにすることが可能かどうか疑問に思っていました。
独自の構造体(値型)を作成しようとしましたが、構造体内でパラメーターなしのコンストラクターを使用できないため、デフォルト値を0から変更する方法が見つかりません。
デフォルト値を変更することは不可能であり、インスタンス化された後にセルごとにマトリックスをループする必要がありますが、それを行う前に念のためにここで確認したいと思います。
解決
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)
の評価対象を設定する方法はありません。
他のヒント
説明のようにデフォルト値を変更する方法はありません。
var someInt = default(int); //this will always be 0, you can't change it
var someReference = default(SomeClass); //this will always be null
msdnの記事 、残念ながら既に言われているものよりも記述的ではありませんが。
値をカプセル化し、必要なデフォルト値のオフセットでのみ公開する構造を作成できます:
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
既に構造体を見ているので、次のようにデフォルト値をシミュレートできます。
public struct MyInt
{
private int _defaultInt;
public int DefaultInt
{
get
{
if (_defaultInt == 0)
return 5;
else
return _defaultInt;
}
set
{
_defaultInt = value;
}
}
}
default(T)
の実装についての私の理解では、ランタイムは、デフォルトで、アプリケーションが要求したときにメモリをゼロにし、C#はゼロを上書きせずにスペースを割り当てます。非数値型のデフォルト値(たとえば、null参照、false)がメモリ内でゼロとして表されるのは、たまたま起こります。これにより、奇妙な動作が発生する可能性があります。たとえば、列挙値をゼロに指定していない場合でも、default(MyEnumType)
はゼロになります。
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; }
}
}