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


82

私はプロパティがクラスに存在するかどうかを知りたいのですが、これを試しました:

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);
}

4
から関連するコードを投稿していただけませんMyClassか?
nattyddubbs 2013年

回答:


126

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

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

これにより、すべてのobject基本クラスに拡張機能が追加されます。この拡張機能を呼び出すと、Type次のように渡されます。

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

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

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

解決策はどちらかです

a)MyClassのインスタンスを拡張機能に提供します

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");

2
つまり、コードは ` , not Type.LabelMyClass.Label`を探しています。
Peter Ritchie

これを拡張システムSystem.Typeにどのように配置しますか。これは実行するコードのどこに行きますか?
Demodave 2015年

1
@ Demodave-拡張メソッドはパブリック静的クラスにあります。詳細については、こちらを参照してください:msdn.microsoft.com/en-GB/library/bb383977.aspx
Jamiec 2015年

このエラーが発生した場合:「タイプGetPropertyメソッドの定義が含まれていません」、この読み:stackoverflow.com/questions/7858469/...
タデイ

26

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

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

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

プロパティが存在する場合(ただし、存在する場合だけではありません)、trueを返します。

私の場合、ASP.NET MVCパーシャルビューを使用していて、プロパティが存在しないか、プロパティ(ブール値)がtrueの場合に何かをレンダリングしたいと考えていました。

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

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

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


nameof演算子の使用に関して、存在しない可能性のあるプロパティの名前を取得することは機能しますか(例外はスローされません)?元の質問の前提は、このプロパティが存在するかどうかわからないということだったのでしょうか。
ゾーイ

試してみて、私の答えを編集して明確にしてみませんか?
Stachu 2018年

2

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

あなたは本当にLabel財産を持っていません。

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

あなたの財産が公開されていない場合は、使用する必要があります BindingFlags.NonPublic、ユースケースに適したフラグをか、他の組み合わせます。詳細については、参照されているAPIドキュメントをお読みください。

編集:

おっと、あなたが電話をかけGetPropertytypeof(MyClass)いることに気づきました。typeof(MyClass)ですTypeことを確認するために何も持たないLabelプロパティを。


使用されるデフォルトのバインディングフラグはInstance|Public|Static、iircです。
LukeH 2013年

@LukeH、よくわからなかったので、「正しい」と書き、「例」を追加しました:)多分Label私有財産です。
zdeslav Vojkovic 2013年

1

受け入れられた回答を結ぶときに、「タイプにGetPropertyの定義が含まれていません」というエラーが発生しました。

これは私が最終的に得たものです:

using System.Reflection;

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

}

0

あなたが私のように拘束している場合:

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

0

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.