2

申し訳ありませんが、質問をグーグルで表現できるフレーズに要約することはできません。

3Dデカルトポイント(x、y、zプロパティとその他のいくつかの機能)であるPt3クラスがあります。私は Pt3 タイプを RegionProvider クラスのプロパティ値の取得/設定として使用しています - Location と Normal のために。

Location プロパティは問題ありません。プロパティがどのように設定されているかは気にしません。

//Location set method 1 - sweet...
RegionProvider Foo = new RegionProvider();
Foo.Location.x = 10;
Foo.Location.y = 20;
Foo.Location.z = 30;

//Location set method 2 - also sweet...
RegionProvider Foo2 = new RegionProvider();
Foo2.Location = new Pt3(10, 20, 30);

ただし、Normal プロパティには異なる動作が必要です。必要に応じて、RegionProvider クラスで入力を Normal プロパティに正規化する必要があります。たとえば、呼び出し元が「通常」の値を 40,50,60 に設定した場合、RegionProvider クラスは 0.4558、0.5698、0.6838 に正規化されます (ベクトルの長さ == 1 を与えるため)。 . 発信者が次のことを行うと、すべてがうまくいきます...

//Normal set method A - sweet...
Foo.Normal = new Pt3(40, 50, 60);

...しかし、彼らがこれを行うと悲しみが続く場合:

//Normal set method B - grief...
Foo2.Normal.x = 40;
Foo2.Normal.y = 50;
Foo2.Normal.z = 60;

...各要素が設定されると、RegionProvider クラスが正規化されるためです。私がやりたいことは、呼び出し元が Normal プロパティの x、y、z を表示できないようにすることで、上記のメソッド 'A' を強制的に使用するようにします。

1 つの解決策は、プロパティ セットをまったく正規化せず、プロパティ get を正規化することですが、これは偽物のように思えます。

価値のあるものとして、ここに私のNormalプロパティ宣言があります:

/// <summary>
/// Property for the objects normal
/// </summary>
public Pt3 Normal
{
    set
    {
        _normal = Bit555ModelCore.NormalizeVector(value);
        this.NotifyPropertyChanged("Normal");
    }
    get
    {
        return _normal;
    }
}

どんな助けでも事前に乾杯....

4

5 に答える 5

0

Pt3おそらく構造体であり、不変の値として扱われる必要があります。

セッターを削除し、コンストラクターを介した座標の設定のみを許可します。その場合、あなたのタイプのユーザーは一度に1つのプロパティを変更できなくなりRegionProvider、の値がいつ変更されたかを常に知ることができNormalます。

これは、 System.Drawing.Pointの動作とほぼ同じですPointが、XとYを設定できるため、次のようなことを試みると、あらゆる種類の問題が発生します。

Foo.Bar.X += 10;

それ以外の

Foo.Bar += new Size(10, 0);
于 2012-07-22T23:18:21.747 に答える
0

同じタイプである必要があると仮定するNormalLocation、Pt3 は単純なプロパティを持つことができます。

public bool CanSetXyz { get; }

の場合Location、このプロパティを に初期化しますtrue。の場合Normalは、 に初期化しfalseます。

次に、X、Y、Z の各プロパティで次のようにします。

private int _x;

public int X
{
    get { return _x; }
    set
    {
        if (!CanSetXyz)
        {
            throw new CantSetXyzException("Can't set X on a Normal point.");
        }
        _x = value;
    }
}

それらが同じ型である必要がない場合は、2 つの間で常に共有されるもので共通の基本クラスを作成する必要があります。その場合、1 つのクラスには X、Y、および Z のセッターがなく、その他にはパブリックセッターがあります。

例:

public abstract class BasePt3
{
    protected int x;
}

public class LocationPt3 : BasePt3
{
    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public LocationPt3(int _x)
    {
        x = _x;
    }
}

public class NormalPt3 : BasePt3
{
    public int X
    {
        get { return x; }
    }

    public NormalPt3(int _x)
    {
        x = _x;
    }
}

編集: X の読み取りを許可する基本クラスを使用した、おそらくより有用な例:

public abstract class BasePt3
{
    protected int x;

    public int X
    {
        get { return x; }
    }
}

public class LocationPt3 : BasePt3
{
    public new int X
    {
        get { return x; }
        set { x = value; }
    }

    public LocationPt3(int _x)
    {
        x = _x;
    }
}

public class NormalPt3 : BasePt3
{
    public new int X
    {
        get { return x; }
    }

    public NormalPt3(int _x)
    {
        x = _x;
    }
}
于 2012-07-22T23:02:57.700 に答える
0

問題は「グッズ」に関するあなたの発言にあると思います。

ベクトル クラス (Pt3) が必要であると判断した場合は、それをそのまま使用します。「Normalize()」メソッドを定義し、明示的に使用します。

とにかく、それは私のアドバイスです。

于 2012-07-22T23:37:29.277 に答える
0

次の 2 つのオプションがあると思います。

  1. クラス全体を不変にすることで、 のプロパティがPt3個別に設定されないようにします。

    class Pt3
    {
        public Pt3(double x, double y, double z)
        {
            X = x;
            Y = y;
            Z = z;
        }
    
        public double X { get; private set; }
        public double Y { get; private set; }
        public double Z { get; private set; }
    }
    
  2. 2 つのクラスを持つ: Pt3Mutableand Pt3Immutable(またはいくつかのより適切な名前)。 Pt3Immutable不変なので、Normal安全に使用できます。Pt3Mutable変更可能であるため、 に使用した場合Location、方法 1 は引き続き機能します。

    次に、キャスト演算子を使用して、2 つの型の間で変換を行うことができます。つまり、 Pt3Mutabletoからの暗黙Pt3Immutable的なキャストと、その逆の明示的なキャストです。

于 2012-07-22T23:52:49.420 に答える
0

Pt3 がクラスの場合、セッター (X、Y、Z) を削除するか、プライベートにします。

于 2012-07-22T22:33:49.813 に答える