2012-04-20 18 views
0

質問を再入力しました。下にスクロールして元に戻すプロパティが汎用プロパティの通知を変更しました

[OK]を、多分私はあなたに全体の画像を与えていたはずです。などのトランスフォームと呼ばれるクラス、メッシュ、衝突、外観は、Componentから派生したすべてとすべてが上記のように宣言されているプロパティが、何もないもあります

public class Movement : Component 
{ 
    private Vector3 linearVelocity; 
    public Vector3 LinearVelocity 
    { 
     get 
     { 
      return linearVelocity; 
     } 
     set 
     { 
      if (value != linearVelocity) 
      { 
       linearVelocity = value; 
       ComponentChangedEvent<Movement>.Invoke(this, "LinearVelocity"); 
      } 
     } 
    } 

    // other properties (e.g. AngularVelocity), which are declared exactly 
    // the same way as above 
} 

:私はこのようになり、多くのクラスを持っています。ここで重要なことは、ComponentChangedEventを呼び出すことです。すべてが完璧に機能しますが、私はそれぞれのプロパティに対して同じロジックを何度も何度も書き直す必要がない方法を探していました。

私は外観がhereであり、一般的なプロパティを使用するアイデアが好きでした。

public class ComponentProperty<TValue, TOwner> 
{ 
    private TValue _value; 

    public TValue Value 
    { 
     get 
     { 
      return _value; 
     } 
     set 
     { 
      if (!EqualityComparer<TValue>.Default.Equals(_value, value)) 
      { 
       _value = value; 
       ComponentChangedEvent<TOwner>.Invoke(
        /*get instance of the class which declares value (e.g. Movement instance)*/, 
        /*get name of property where value comes from (e.g. "LinearVelocity") */); 
      } 
     } 
    } 

    public static implicit operator TValue(ComponentProperty<TValue, TOwner> value) 
    { 
     return value.Value; 
    } 

    public static implicit operator ComponentProperty<TValue, TOwner>(TValue value) 
    { 
     return new ComponentProperty<TValue, TOwner> { Value = value }; 
    } 
} 

それから私はこのようにそれを使用します:

public class Movement : Component 
{ 
    public ComponentProperty<Vector3, Movement> LinearVelocity { get; set; } 
    public ComponentProperty<Vector3, Movement> AngularVelocity { get; set; } 
} 

しかし、私は線速度がから来ても、それは文字列として名前だインスタンスを取得することはできませんよ、私はこのようになります思い付きました。だから私の質問は、もしこれが全て可能ならば...

しかし、それは私が行っていたやり方とは別の選択肢がないように思えます。

元の質問:私はこのような何かを持っている別の文脈では

public class Foo 
{ 
    public int Bar { get; set; } 
} 

プロパティ

から宣言クラスのインスタンスを取得します。私は、プロパティを持つクラスを持っています:

Foo fooInstance = new Foo(); 
DoSomething(fooInstance.Bar); 

次に、DoSomethingparameter以外何も持っていないことをfooInstanceから取得する必要があります。文脈からは、整数がDoSomethingに渡されるのではなく、intのパブリックプロパティのみが渡されると仮定するのが節約されます。

public void DoSomething(int parameter) 
{ 
    // need to use fooInstance here as well, 
    // and no, it is not possible to just pass it in as another parameter 
} 

これはまったく可能ですか?リフレクションを使用するか、おそらくプロパティのカスタム属性Barを使用しますか?

+4

デザインを再考する必要があります。これは不可能です。 – BrokenGlass

+0

私はあなたが求めているものを得られない...なぜあなたは議論として 'フー'を与えることができないのですか? – log0

+0

なぜ別のパラメータとして渡すことができないのですか? –

答えて

2

INotifyPropertyChangedの実装にはいくつかの方法があります。インターフェイスを実装せず、イベントを別の方法で呼び出さない限り、ほぼ同じことをやっています。しかし、すべてのソリューションがあなたにも当てはまります。

  1. 同様に、文字列パラメータ:OnPropertyChanged("Property")でメソッドを呼び出します。
  2. プロパティを使用するラムダでメソッドを呼び出します:OnPropertyChanged(() => Property)。これの利点は、コンパイル時にタイプミスやリファクタリングに適しているかどうかがチェックされることです。
  3. OnPropertyChanged()の名前を挿入するには、caller informationを使用します。これはC#5でも動作します。
  4. Castle DynamicProxyのようなものを使用して、実行時にメソッドを呼び出す派生クラスを作成します。つまり、プロパティーをvirtualにする必要があり、Castleのインスタンスのみを作成する必要があることを意味します。
  5. コンパイル後にプロパティのコードを変更してメソッドを呼び出すには、AOPフレームワークを使用します。
+0

ありがとう、私はこれらを見ていきます。 INotifyPropertyChangedを実装すると、そのトリックも行う必要があります。発信者情報(および他のC#5のもの)は面白く見えますが、それは未来のものです。 – christoph

0

fooInstanceを取得する方法はありません。parameterです。parameterが値によって渡され、fooInstance.Barの値のコピーのみであるが、それはもはや言われていることfooInstance

を行うには何も持っていない、明白な解決策は、この

public void DoSomething(Foo parameter) 
{ 
    // need to use fooInstance here as well, 
    // and no, it is not possible to just pass it in as another parameter 
} 
3

ようDoSomethingを書くことですそれがなるので、なぜ、

DoSomething(fooInstance); 

あなたの関数は、パラメータの代わりにオブジェクトを受け取ります、:)あなたはdoSomethingのにちょうどプロパティを送りたいん、それをオブジェクト全体を送信します。この関数のオーバーロードを使用して、古いコードが壊れていないことを確認できます。

0

プロパティはフィールドであり、ヒープ上のオブジェクト(つまりそのアドレス)への参照を返します。 propertyが参照型でない場合、objectの値を返します。

だから、あなたは

DoSomething(fooInstance.Bar); 

ような何かをしたときにあなただけのメソッドにオブジェクトバーのアドレスを渡します。

バーが参照型(つまりクラス)の場合。 Mr.FooにMr.Bar(462、マリオン郡、インディアナ)のアドレスがあるとします。 Mrs.CLRはMr.FooにMr.Barの住所を尋ねます。そして、この住所にMr.Barの住所が必要な人に知らせる。 CLRがFooにBarの住所を尋ねたことを誰かが知るだろうか?彼はマリオン郡(インディアナ州)462の住所のみを受け取った

値オブジェクト(int、double、structsなど)の場合、Mr.FooはBarという名前のクールなmp3トラックを持っています。 Mrs.CLRはそのmp3トラックのコピーを作成し、誰かに送信します。彼のMP3トラックバーはMr.Fooのトラックのコピーであると誰かが知っているだろうか?

あなたは誰かがMr.Foo知りたいのであれば、あなたは彼にMr.Fooのアドレスを渡す必要があります。

DoSomething(fooInstance); 

このアドレス誰かとMr.Fooを訪問し、について彼に尋ねることができますMr.Barのアドレスを入力するか、mp3トラックのコピーを作成してください:)

+0

です。実際には、パラメータは関数によく似ています。プロパティのローカル値を返す/設定するゲッターとセッターがあります。このプロパティが参照型の場合、オブジェクトの新しい参照が渡され、その参照はメモリ内の同じオブジェクトになります。これは値型なので、値の新しいコピーを戻します。 –

+0

@ShawnL、知っている、そのプロパティは実際にget_Nameとset_Name関数です:)ただ単純化したい –

+0

ありがとうlazyberezovsky、カラフルな説明:) – christoph

関連する問題