0

質問を言い換えました。原文は下にスクロール

わかりました、多分私はあなたに全体像を与えるべきでした. 私は次のような多くのクラスを持っています:

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
}

Transform、Mesh、Collider、Appearance などと呼ばれるクラスもあります。これらはすべてから派生しComponent、上記のように宣言されたプロパティのみを持ちます。ここで重要なのは、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; }
}

しかし、LinearVelocity が由来するインスタンスも文字列としての名前も取得できません。だから私の質問は、これがすべて可能かどうかでした...

しかし、各プロパティのこのロジックを手動で記述して、これまでどおりに実行する以外に選択肢はないようです。

元の質問:

プロパティから宣言クラスのインスタンスを取得する

プロパティを持つクラスがあります:

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

別のコンテキストでは、次のようなものがあります。

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

次に、DoSomething私はfooInstance何も持たないことから取得する必要がありparameterます。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

4 に答える 4

3

プロパティだけを DoSomething に送信し、オブジェクト全体を送信するのはなぜですか :)、そのため、次のようになります。

DoSomething(fooInstance);

関数は、パラメーターの代わりにオブジェクトを受け入れます。この関数のオーバーロードを使用して、古いコードが壊れないようにすることができます。

于 2012-04-20T16:40:33.477 に答える
2

の実装に対処するには、いくつかの方法がありますINotifyPropertyChanged。インターフェイスを実装せず、別の方法でイベントを発生させることを除いて、ほとんど同じことをしています。しかし、すべての解決策はあなたにも当てはまります。

  1. あなたと同じように、文字列パラメーターでメソッドを呼び出します: OnPropertyChanged("Property").
  2. プロパティを使用するラムダでメソッドを呼び出します: OnPropertyChanged(() => Property)。これの利点は、コンパイル時にタイプミスがチェックされ、リファクタリングしやすいことです。
  3. 呼び出し元情報を使用して、プロパティの名前を挿入します: OnPropertyChanged(). これは C# 5 で機能します。
  4. Castle DynamicProxy などを使用して、実行時にメソッドを呼び出す派生クラスを作成します。これは、プロパティvirtualを作成する必要があり、Castle を介してのみクラスのインスタンスを作成する必要があることを意味します。
  5. AOP フレームワークを使用して、コンパイル後にプロパティのコードを変更し、メソッドを呼び出します。
于 2012-04-20T17:22:21.927 に答える
0

fooInstanceから入手する方法はありませんparameterparameterは値で渡され、 の値のコピーにすぎfooInstance.Barません。fooInstance

DoSomethingそうは言っても、明らかな解決策はこのように書くことです

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
}
于 2012-04-20T16:40:31.410 に答える
0

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

だから、あなたが何かをするとき

DoSomething(fooInstance.Bar);

オブジェクト Bar のアドレスをメソッドに渡すだけです。

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

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

したがって、誰かに Mr.Foo のことを知ってもらいたい場合は、Mr.Foo のアドレスを彼に渡す必要があります。

DoSomething(fooInstance);

このアドレスを使用して、誰かが Mr.Foo を訪問して Mr.Bar のアドレスを尋ねたり、彼の mp3 トラックのコピーを作成したりできます :)

于 2012-04-20T16:41:13.067 に答える