3

私は現在nHibernateに歯を食いしばっており、永続オブジェクトのプロパティに動的にアクセスすることに関して質問がありました。

私のクラスには次のクラスがありますDomain

public class Locations {
    public virtual string CountryCode;
    public virtual string CountryName;
}

ここで、Locationsオブジェクトへの参照があると仮定して、このようなことを行う方法はありますか?

Locations myCountry = new LocationsRepository().GetByCountryCode("US");
myCountry.Set("CountryName", "U.S.A.");

する代わりに:

myCountry.CountryName = "U.S.A."

反省なし?

4

5 に答える 5

1

プロパティを持つ通常のオブジェクトのように動作し、同時に辞書のように動作するものを探しています。.NET4を使用している場合は、まさにそれであるExpandoObjectを見ることができます。

于 2012-05-15T13:04:31.910 に答える
1

リフレクションを回避する目的がパフォーマンスの向上である場合、簡単な解決策は、次のようなすべてのプロパティを使用して機能をハードコーディングすることです。

public class Locations {
    public virtual string CountryCode;
    public virtual string CountryName;

    public void Set(string propertyName, string value) {
        if (propertyName == "CountryCode") this.CountryCode = value;
        else if (propertyName == "CountryName") this.CountryName = value;
        else throw new ArgumentException("Unrecognized property '" + propertyName + "'");
    }
}

T4テンプレートSetを使用して、すべてのドメインクラスのメソッドをプログラムで生成することにより、このアプローチを簡単に維持できます。実際、T4テンプレートを使用してアダプターとシリアライザーを生成し、実行時のリフレクションのコストを回避しながら、コンパイル時のコード生成のリフレクションの柔軟性を獲得して、独自のコードベースで同様のことを行います。

于 2012-05-15T12:34:10.603 に答える
1

あなたが「リフレクションなし」と言ったことは知っていますが、リフレクションはすべて悪いわけではありません (確かに、人々が考えるほど遅くはありません)。したがって、ここでリフレクション ソリューションについて言及する価値があります。

using System.Reflection;

typeof(Locations).GetProperty("CountryName").SetValue(myCountry, "U.S.A.", null);

プーフ、完了。

于 2012-05-15T12:46:33.533 に答える
1

私は StackOverflow に関する自分の質問に答えるのが嫌いで、皆さんの回答に感謝していますが、実際に私のために回答してくれる人はいませんでした。いくつかの調査の後、NHibernate の最新バージョンが動的モデルを提供することがわかりました。

便利ではありますが、実験的な性質があるため、本番環境で使用することに少し不安を感じたため、さらに調査を行いました。SE 自身の Marc Gravell が Fastmember と呼ばれる彼の HyperDescriptor ライブラリの後継を作成したことを発見しまし。DLR が提供する速度向上を利用し、リフレクションのより単純な構文と組み合わせます。FastMember アクセスを単純な GetValue および SetValue メソッドとして基本エンティティ クラスに実装し、ビジネスを行っていました。

于 2012-06-10T22:02:54.663 に答える
0

反省がなければ、これはアイデアになる可能性があります。

public class Locations 
{
  private Dictionary<string, object> _values;
  public Locations() 
  {
    _values = new Dictionary<string, object>();
  }
  public void Set(string propertyName, object value)
  {
     if(!_values.ContainsKey(propertyName))
        _values.Add(propertyName, value);
     else
        _values[propertyName] = value;
  }
  public object Get(string propertyName)
  {
     return _values.ContainsKey(propertyName) ? _values[propertyName] : null;
  }

  public string CountryCode
  {
     get{ return Get("CountryCode"); }
     set{ Set("CountryCode", value); }
  }
}

このようにして、リフレクションなしでプロパティにアクセスし、単一のメソッドでプロパティを変更できます。私はこのコードをテストしていませんが、これが「プロパティに直接アクセスできない」という意味であることを願っています。

于 2012-05-15T12:33:39.640 に答える