danielgomezdidier
danielgomezdidier

Reputation: 401

Exclude property from getType().GetProperties()

Hi i'm working in a class library using C#, and i have some classes with some properties.

I just wanna know if i can add something to exclude some properties form the getType().GetProperties().

An example of what i want:

class Test
{
    public string one { get; set; }
    public string two {get ; set;}
}

and if i do this:

static void Main(string[] args)
{

       Test t = new Test();
       Type ty = t.GetType();
       PropertyInfo[] pinfo = ty.GetProperties();

       foreach (PropertyInfo p in pinfo)
       {
           Console.WriteLine(p.Name);
       }
  }

i want the output be something like this:

one

or just one of the properties.

Is possible to do something like that? i don't know if there some kind of modifiers or annotations in C#, that allow me to do what i want.

Thanks.

Upvotes: 35

Views: 28831

Answers (7)

LucaSC
LucaSC

Reputation: 792

Another option is adding inheritance. You keep on your base class only what you want to get.

class TestBase
{
    public string one { get; set; }
}

class Test : TestBase
{
    public string two { get; set; }
}


TestBase t = new TestBase();
Type ty = t.GetType();
PropertyInfo[] pinfo = ty.GetProperties();

foreach (PropertyInfo p in pinfo)
{
    Console.WriteLine(p.Name);
}

This prints:

one

Upvotes: 0

bniwredyc
bniwredyc

Reputation: 8829

Extension methods and attributes will help you:

public class SkipPropertyAttribute : Attribute
{
}

public static class TypeExtensions
{
    public static PropertyInfo[] GetFilteredProperties(this Type type)
    {
        return type.GetProperties().Where(pi => pi.GetCustomAttributes(typeof(SkipPropertyAttribute), true).Length == 0).ToArray();
    }       
}

public class Test
{
    public string One { get; set; }

    [SkipProperty]
    public string Two { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var t = new Test();
        Type ty = t.GetType();

        PropertyInfo[] pinfo = ty.GetFilteredProperties();
        foreach (PropertyInfo p in pinfo)
        {
            Console.WriteLine(p.Name);
        }

        Console.ReadKey();
    }
}

UPDATE:

Little more elegant implementation of the GetFilteredProperties (thanks to Marc Gravell):

public static class TypeExtensions
{
    public static PropertyInfo[] GetFilteredProperties(this Type type)
    {
        return type.GetProperties()
              .Where(pi => !Attribute.IsDefined(pi, typeof(SkipPropertyAttribute)))
              .ToArray();
    }
}

Upvotes: 48

adprocas
adprocas

Reputation: 1913

Although I prefer, and am going to use, the attribute way, I did get this working in a different way that might help the OP.

Here's an example:

PropertyInfo[] properties = record.GetType().GetProperties().Where(p => !"Description".Equals(p.Name)).ToArray();

This will exclude any properties that are named "Description". If you're not able to change the class that contains the properties this could be an option. Again, I prefer the attribute way mentioned above.

Upvotes: 0

Jon Seigel
Jon Seigel

Reputation: 12401

I'm not sure what the domain is here, so I'm going out on a limb...

Usually what you want to do is use Attributes to tag the properties to include in your metadata searching, not the other way around.

Upvotes: 1

Jarrett Meyer
Jarrett Meyer

Reputation: 19573

You could put a custom attribute on your type.

public class DoNotIncludeAttribute : Attribute
{
}

public static class ExtensionsOfPropertyInfo
{
    public static IEnumerable<T> GetAttributes<T>(this PropertyInfo propertyInfo) where T : Attribute
    {
        return propertyInfo.GetCustomAttributes(typeof(T), true).Cast<T>();
    }
    public static bool IsMarkedWith<T>(this PropertyInfo propertyInfo) where T : Attribute
    {
        return property.GetAttributes<T>().Any();
    }
}
public class Test
{
    public string One { get; set; }

    [DoNotInclude]
    public string Two { get; set; }
}

Then, in your runtime, you can search for properties that are not hidden.

foreach (var property in properties.Where(p => !p.IsMarkedWith<DoNotIncludeAttribute>())
{
    // do something...
}

It won't be really hidden, but it wouldn't show up in the enumeration.

Upvotes: 8

Jerod Venema
Jerod Venema

Reputation: 44632

I don't think you can do this directly, but you could add your own custom attributes and filter them out yourself...

Upvotes: 0

AaronLS
AaronLS

Reputation: 38367

With the PropertyInfo object you can examine the GetCustomAttributes of the property. So you could add attributes to your properties when you declare them, and then when you are reflecting against the properties, you can choose only the properties that are marked with the attributes you desire.

Of course if you are actually wanting to somehow prevent someone from reflectively getting your properties, this is not the solution you want.

Edit: I'm sorry you want GetCustomAttributes, fixed. See this: http://msdn.microsoft.com/en-us/library/kff8s254.aspx

Upvotes: 0

Related Questions