17

構造体のデフォルト状態を設定またはオーバーライドすることはできますか?

例として、私は

enum something{a,b,c,d,e};

およびその列挙型の 2 つの値をリンクする構造

struct SomethingData
{
    something type;
    int Value;
    double Multipler;

    SomethingData(something enumVal, int intVal, double DblVal) {...}
}

しかし、デフォルトの状態が

SomethingData(something.c,0,1);
4

12 に答える 12

13

Structコンストラクターは、次の違いを除いて、クラスコンストラクターに似ています。

構造体には、明示的なパラメーターなしのコンストラクターを含めることはできません。構造体メンバーは、デフォルト値に自動的に初期化されます。構造体は、base(argument-list)の形式で初期化子を持つことはできません。

http://msdn.microsoft.com/en-us/library/aa288208(v=vs.71).aspx

したがって、簡単に言えば、デフォルトのコンストラクターをオーバーライドすることはできません(すべての構造体にはパラメーターのないコンストラクターがあり、非表示にしたりオーバーライドしたりすることはできません)...

于 2010-12-21T17:17:55.777 に答える
8

できません。構造体には常に、すべてのメンバーをデフォルト値に設定するデフォルトのコンストラクターがあります(null参照型、0数値型、falseboolなど)。この動作は変更できません。

于 2010-12-21T17:19:29.670 に答える
1

クラス オブジェクトを作成すると、すべてのインスタンス フィールドが (クラス コンストラクターでさえ) アクセスできるようになります。また、配列を割り当てると、配列にアクセスできるようになる前にすべての要素が存在します。これらのアクションは両方とも、それらのフィールドまたは要素に割り当てられたすべてのメモリを、そこに格納されるデータ型に関係なくゼロに設定します。

クラス型の格納場所が存在するようになると、最初は null 参照が保持されます。構造型の格納場所が存在するようになると、そのすべてのフィールド (およびその中の構造のフィールド) が同時に存在します。コンストラクターを使用することによってのみ生成できるクラス オブジェクト インスタンスとは異なり、構造体型の格納場所は、構造体自体のコードを使用せずに生成されます。したがって、構造体の定義は、「インスタンス」[つまり、構造体型の格納場所] が出現したときに何が起こるべきかを決定することはできません。

構造体は、基本的に、ダクト テープで結合されたフィールドのコレクションです。構造体が他の何かのように動作することになっている場合、通常はそのフィールドをプライベートにし、不変であるふりをする必要があります [構造体の代入は、ソースからの対応する値ですべてのフィールドを上書きすることによって宛先構造体を実際に変更しますが、構造体定義この件について発言権はありません]。ただし、構造体が、関連するが独立した値 (たとえば、ポイントの座標) の固定セットをカプセル化することになっている場合、それぞれの型に有効な値の任意の組み合わせを個別に収容できます。、構造体は単にそのフィールドを公開する必要があります。「変更可能な構造体は悪だ」と不満を言う人もいるかもしれませんが、その悪は構造体で自己変更メソッドを呼び出す場合にのみ当てはまります。状態をフィールドとして公開する構造体は、変数のコレクションがガムテープでくっついているような振る舞いをします。必要なものがダクトテープでくっついた変数のコレクションである場合、構造体を不変のふりをさせようとすると、プログラミングが難しくなります。

于 2013-05-23T22:22:41.187 に答える
1

構造体の既定の (パラメーターなしの) コンストラクターをオーバーライドすることはできません。パラメータを取る新しいコンストラクタのみを追加できます。

http://csharp.2000things.com/2010/10/03/108-defining-a-constructor-for-a-struct/

于 2010-12-21T17:30:21.223 に答える
0

プロパティを取得/設定するたびに、デフォルト値を設定する必要があります InitDefaultValues() メソッドを呼び出します

private string _numberDecimalSeparator;
public string NumberDecimalSeparator
{
    get
    {
        InitDefaultValues();
        return _numberDecimalSeparator;
    }
    set
    {
        InitDefaultValues(); 
        _numberDecimalSeparator = value;
    }
}

...

private void InitDefaultValues()
{
    if (!_inited)
    {
        _inited = false;
        var ci = CultureInfo.CurrentCulture;
         _numberDecimalSeparator = ci.With(x => x.NumberFormat).Return(x => x.NumberDecimalSeparator, ".");

        ...
    }
}
于 2013-06-09T16:56:32.943 に答える
0

多少の関連: 私はしばしば、新しいオブジェクト初期化子構文を不変の値型で使用したいと考えてきました。ただし、典型的な不変値型の実装の性質を考えると、プロパティは読み取り専用であるため、その構文を利用する方法はありません。

私はこのアプローチを思いつきました。私の意見では、これでも値型の不変性は満たされますが、値型のインスタンス化を担当するコードは、内部データの初期化をより細かく制御できます。

struct ImmutableValueType
{
    private int _ID;
    private string _Name;

    public int ID
    {
        get { return _ID; }
    }

    public string Name
    {
        get { return _Name; }
    }

    // Infuser struct defined within the ImmutableValueType struct so that it has access to private fields
    public struct Infuser
    {
        private ImmutableValueType _Item;

        // write-only properties provide the complement to the read-only properties of the immutable value type
        public int ID
        {
            set { _Item._ID = value; }
        }

        public string Name
        {
            set { _Item._Name = value; }
        }

        public ImmutableValueType Produce()
        {
            return this._Item;
        }

        public void Reset(ImmutableValueType item)
        {
            this._Item = item;
        }

        public void Reset()
        {
            this._Item = new ImmutableValueType();
        }

        public static implicit operator ImmutableValueType(Infuser infuser)
        {
            return infuser.Produce();
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        // use of object initializer syntax made possible by the Infuser type
        var item = new ImmutableValueType.Infuser
        {
            ID = 123,
            Name = "ABC",
        }.Produce();

        Console.WriteLine("ID={0}, Name={1}", item.ID, item.Name);
    }
}
于 2010-12-21T18:55:02.563 に答える
0

私の解決策。それも同様に機能します。

public struct DisplayOptions
{
    public bool isUpon;
    public bool screenFade;

    public static DisplayOptions Build()
    {
        // Return default value
        return new DisplayOptions(true, true);
    }

    DisplayOptions(bool isUpon, bool screenFade)
    {
        this.isUpon = isUpon;
        this.screenFade = screenFade;
    }

    public DisplayOptions SetUpon(bool upon)
    {
        this.isUpon = upon;
        return this;
    }

    public DisplayOptions SetScreenFade(bool screenFade)
    {
        this.screenFade = screenFade;
        return this;
    }
}

デフォルト値を使用

        // Use default
        UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build());
        // Use custome
        UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build().SetScreenFade(false));
        UIMaster.Instance.StartScreen("Screen 2", DisplayOptions.Build().SetUpon(false));
于 2017-07-06T07:07:09.503 に答える
-1

これはうまくいくはずです

public struct MyStruct 
{
    private string myName;
    private int? myNumber;
    private bool? myBoolean;
    private MyRefType myType;

    public string MyName
    {
        get { return myName ?? "Default name"; }
        set { myName= value; }
    }
    public int MyNumber
    {
        get { return myNumber ?? 42; }
        set { myNumber = value; }
    }
    public bool MyBoolean
    {
        get { return myBoolean ?? true; }
        set { myBoolean = value; }
    }
    public MyRefType MyType 
    {
        get { return myType ?? new MyRefType(); }
        set { myType = value; }
    }

    //optional
    public MyStruct(string myName = "Default name", int myNumber = 42, bool myBoolean = true)
    {
        this.myType = new MyRefType();
        this.myName = myName;
        this.myNumber = myNumber;
        this.myBoolean = myBoolean;
    }
}

[TestClass]
public class MyStructTest
{
    [TestMethod]
    public void TestMyStruct()
    {
        var myStruct = default(MyStruct);
        Assert.AreEqual("Default name", myStruct.MyName);
        Assert.AreEqual(42, myStruct.MyNumber);
        Assert.AreEqual(true, myStruct.MyBoolean);
        Assert.IsNotNull(myStruct.MyType);
    }
}
于 2014-05-02T20:30:20.443 に答える