开发者

Exclude property from getType().GetProperties()

开发者 https://www.devze.com 2022-12-16 08:09 出处:网络
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().

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; 开发者_如何学Cset; }
    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.


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


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.


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.


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


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


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.


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
0

精彩评论

暂无评论...
验证码 换一张
取 消