110

I try to know if a property exist in a class, I tried this :

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

I don't understand why the first test method does not pass ?

[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);
}
user11251276
  • 53
  • 1
  • 8
TheBoubou
  • 19,487
  • 54
  • 148
  • 236

6 Answers6

165

Your method looks like this:

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

This adds an extension onto object - the base class of everything. When you call this extension you're passing it a Type:

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

Your method expects an instance of a class, not a Type. Otherwise you're essentially doing

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

Then

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

As @PeterRitchie correctly points out, at this point your code is looking for property Label on System.Type. That property does not exist.

The solution is either

a) Provide an instance of MyClass to the extension:

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

b) Put the extension on System.Type

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

and

typeof(MyClass).HasProperty("Label");
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • 3
    i.e. your code is looking for` Type.Label`, not `MyClass.Label`. – Peter Ritchie Mar 11 '13 at 14:40
  • How would one put this on the extension System.Type where would that be found/. Where does this go in the code to execute? – Demodave Mar 20 '15 at 14:43
  • 1
    @Demodave - extension methods are just in a public static class. See here for more info: https://msdn.microsoft.com/en-GB/library/bb383977.aspx – Jamiec Mar 20 '15 at 14:48
  • 1
    If you get this error: "Type does not contain a definition for GetProperty" then read this: http://stackoverflow.com/questions/7858469/missing-type-getproperty-method-in-windows-8-developer-preview – tedi May 17 '17 at 07:14
  • typeof(TEntity).HasProperty doesn't exist – Demodave Jun 30 '22 at 17:23
  • @Demodave In this question, the OP had written that as an extension method. Read the question. – Jamiec Jul 01 '22 at 08:20
30

This answers a different question:

If trying to figure out if an OBJECT (not class) has a property,

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

returns true if (but not only if) the property exists.

In my case, I was in an ASP.NET MVC Partial View and wanted to render something if either the property did not exist, or the property (boolean) was true.

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

helped me here.

Edit: Nowadays, it's probably smart to use the nameof operator instead of the stringified property name.

Stachu
  • 5,677
  • 3
  • 30
  • 34
  • Regarding the use of the `nameof` operator, will it work (not thrown an exception) to get the name of a property that may not exist? Since the premise of the original question was that we don't know if this property exists? – Zoe Oct 24 '18 at 14:17
  • Why don't you try it and then edit my answer to clarify? – Stachu Oct 24 '18 at 14:36
5

I got this error: "Type does not contain a definition for GetProperty" when tying the accepted answer.

This is what i ended up with:

using System.Reflection;

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

}
tedi
  • 6,350
  • 5
  • 52
  • 67
2

There are 2 possibilities.

You really don't have Label property.

You need to call appropriate GetProperty overload and pass the correct binding flags, e.g. BindingFlags.Public | BindingFlags.Instance

If your property is not public, you will need to use BindingFlags.NonPublic or some other combination of flags which fits your use case. Read the referenced API docs to find the details.

EDIT:

ooops, just noticed you call GetProperty on typeof(MyClass). typeof(MyClass) is Type which for sure has no Label property.

Zdeslav Vojkovic
  • 14,391
  • 32
  • 45
0

If you are binding like I was:

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

I'm unsure of the context on why this was needed, so this may not return enough information for you but this is what I was able to do:

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

In my case I'm running through properties from a form submission and also have default values to use if the entry is left blank - so I needed to know if the there was a value to use - I prefixed all my default values in the model with Default so all I needed to do is check if there was a property that started with that.

C Gil
  • 44
  • 3