4

私は特定の方法で回避しようとしているという共通の問題を抱えています。

基本的にWinformsでは、コントロールの「DisplayMember」と「ValueMember」をフォームに設定しようとしています。通常は次のように設定します。

this.testCombobox.DisplayMember = "PropertyOne";
this.testCombobox.ValueMember = "PropertyTwo";

これを次のように書き換えたい。

this.testCombobox.DisplayMember = ClassOne.GetPropertyName(c => c.PropertyOne);
this.testCombobox.ValueMember = ClassOne.GetPropertyName(c => c.PropertyTwo);

(注: ここでオブジェクトの作成を保存するには、2 つのメソッド呼び出しを静的にする必要があります)

これを行おうとしているすべてのクラスは、基本クラス「BaseObject」から継承するため、次のようにメソッドを追加しました。

public static string GetPropertyName<T, P>(Expression<Func<T, P>> action) where T : class
{
    MemberExpression expression = action.Body as MemberExpression;
    return expression.Member.Name;
}

ただし、これを使用するには、代わりに次のコードを記述する必要があります。

this.testCombobox.DisplayMember = BaseObject.GetPropertyName((ClassOne c) => c.PropertyOne);

私の質問は、私が望むものを達成するためにどのようにメソッドを書き直すのBaseObject.GetPropertyNameですか? 私はとても近いと感じていますが、それを変える方法が思いつきません。

4

3 に答える 3

4

現在の GetPropertyName メソッドはジェネリック T を開いたままにします。したがって、メソッドを使用するときに指定しないため、コンパイラはコンパイル時に解決できません。

ただし、基本クラスをジェネリックにし、かつ派生クラスで T を指定し、かつ (基本クラスではなく) 派生クラスのメソッドを使用するように指定すると、機能します。

このような:

public class BaseClass<T> {
    public static string GetPropertyName<P>(Expression<Func<T, P>> action) {
        MemberExpression expression = action.Body as MemberExpression;
        return expression.Member.Name;
    }
}

public class ClassOne : BaseClass<ClassOne> {
    public string PropertyOne { get; set; }
}
public static class Test {
    public static void test() {
        var displayMember = ClassOne.GetPropertyName(x => x.PropertyOne);
    }
}
于 2013-07-18T11:29:29.667 に答える
4

プロパティ名を抽出するヘルパー クラスを作成しました

  public static class PropertySupport
  {       
    public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
    {
      if (propertyExpression == null)
      {
        throw new ArgumentNullException("propertyExpression");
      }

      var memberExpression = propertyExpression.Body as MemberExpression;
      if (memberExpression == null)
      {
        throw new ArgumentException("Invalide Expression", "propertyExpression");
      }             
      return memberExpression.Member.Name;
    }
  }

そして、次のように使用できます:

PropertySupport.ExtractPropertyName(() => DateTime.Now)

「今」を返します

編集

テスト コンソール アプリは次のとおりです。

  public static class PropertySupport
  {       
    public static string ExtractPropertyName<T>(Expression<Func<T>> propertyExpression)
    {
      if (propertyExpression == null)
      {
        throw new ArgumentNullException("propertyExpression");
      }

      var memberExpression = propertyExpression.Body as MemberExpression;
      if (memberExpression == null)
      {
        throw new ArgumentException("", "propertyExpression");
      }      
      return memberExpression.Member.Name;
    }
  }
  public class MyClass
  {
    public MyClass PropertyOne { get; set; }
  }
  class Program
  {    
    static void Main(string[] args)
    {      
      Console.WriteLine(PropertySupport.ExtractPropertyName(() => new MyClass().PropertyOne));
      Console.ReadKey();
    }   
  }
于 2013-07-18T11:20:39.713 に答える