web-dev-qa-db-ja.com

プロパティがクラスに存在するかどうかを確認します

クラスにプロパティが存在するかどうかを確認しようとすると、私はこれを試しました:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

最初のテスト方法が合格しない理由がわかりませんか?

[TestMethod]
public void Test_HasProperty_True()
{
    var res = typeof(MyClass).HasProperty("Label");
    Assert.IsTrue(res);
}

[TestMethod]
public void Test_HasProperty_False()
{
    var res = typeof(MyClass).HasProperty("Lab");
    Assert.IsFalse(res);
}
72
Kris-I

メソッドは次のようになります。

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

これにより、拡張機能がobject-everythingの基本クラスに追加されます。この拡張機能を呼び出すとき、Typeを渡します:

var res = typeof(MyClass).HasProperty("Label");

メソッドは、Typeではなく、クラスのinstanceを想定しています。そうでなければ、あなたは本質的にやっている

typeof(MyClass) - this gives an instanceof `System.Type`. 

それから

type.GetType() - this gives `System.Type`
Getproperty('xxx') - whatever you provide as xxx is unlikely to be on `System.Type`

@PeterRitchieが正しく指摘しているように、この時点でコードはSystem.TypeのプロパティLabelを探しています。そのプロパティは存在しません。

解決策は

a)MyClassのinstanceを拡張機能に提供します。

var myInstance = new MyClass()
myInstance.HasProperty("Label")

b)System.Typeに拡張機能を配置します

public static bool HasProperty(this Type obj, string propertyName)
{
    return obj.GetProperty(propertyName) != null;
}

そして

typeof(MyClass).HasProperty("Label");
98
Jamiec

これは別の質問に答えます:

OBJECT(クラスではない)にプロパティがあるかどうかを把握しようとすると、

OBJECT.GetType().GetProperty("PROPERTY") != null

プロパティが存在する場合(だけでなく)、trueを返します。

私の場合、ASP.NET MVCパーシャルビューで、プロパティが存在しないか、プロパティ(ブール値)が真の場合に何かをレンダリングしたかったのです。

@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) ||
        Model.AddTimeoffBlackouts)

ここで助けてくれました。

編集:現在、文字列化されたプロパティ名の代わりにnameof演算子を使用するのが賢明です。

18
Stachu

2つの可能性があります。

Labelプロパティが本当にありません。

適切な GetProperty overload を呼び出して、正しいバインディングフラグを渡す必要があります。 BindingFlags.Public | BindingFlags.Instance

プロパティがパブリックでない場合は、BindingFlags.NonPublicまたはユースケースに適合するフラグのその他の組み合わせを使用する必要があります。詳細については、参照されているAPIドキュメントをお読みください。

編集:

おっと、typeof(MyClass)GetPropertyを呼び出したことがわかりました。 typeof(MyClass)Typeであり、Labelプロパティはありません。

2

私はこのエラーを受け取りました:受け入れられた答えを結ぶとき、「タイプにはGetPropertyの定義が含まれていません」。

これは私が終わったものです:

using System.Reflection;

if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null)
{

}
1
Tadej

これがなぜ必要であったかについての文脈は不明であるため、これはあなたに十分な情報を返さないかもしれませんが、これは私ができることです:

if(typeof(ModelName).GetProperty("Name of Property") != null)
{
//whatevver you were wanting to do.
}

私の場合、フォーム送信からプロパティを実行しており、エントリが空白のままの場合に使用するデフォルト値もあります-したがって、使用する値があるかどうかを知る必要がありました-モデル内のすべてのデフォルト値にプレフィックスを付けましたデフォルトで、必要なのは、それで始まるプロパティがあるかどうかを確認することだけです。

0
C Gil

私のようにバインドしている場合:

<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2")  %>
0
Ben