从getType()中排除属性.GetProperties()

时间:2010-01-12 19:44:10

标签: c# .net reflection

您好我正在使用C#在类库中工作,我有一些带有一些属性的类。

我只想知道我是否可以添加一些内容来排除getType().GetProperties()中的某些属性。

我想要的一个例子:

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

如果我这样做:

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

我希望输出是这样的:

one

或只是其中一个属性。

有可能做那样的事吗?我不知道C#中是否有某种修饰符或注释,这使我能够做我想做的事。

感谢。

6 个答案:

答案 0 :(得分:27)

扩展方法和属性可以帮助您:

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

更新:

GetFilteredProperties的更优雅的实现(感谢Marc Gravell):

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

答案 1 :(得分:5)

您可以在类型上添加自定义属性。

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

然后,在运行时,您可以搜索未隐藏的属性。

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

它不会被隐藏,但它不会出现在枚举中。

答案 2 :(得分:1)

我不确定这个域名是什么,所以我出去了......

通常您要做的是使用Attribute来标记包含属性,而不是相反。

答案 3 :(得分:0)

使用PropertyInfo对象,您可以检查属性的GetCustomAttributes。因此,您可以在声明属性时向属性添加属性,然后在反映属性时,只能选择使用所需属性标记的属性。

当然,如果你真的想以某种方式阻止某人反思性地获取你的财产,这不是你想要的解决方案。

编辑:很抱歉你想要GetCustomAttributes,修复。看到这个: http://msdn.microsoft.com/en-us/library/kff8s254.aspx

答案 4 :(得分:0)

我认为您不能直接执行此操作,但您可以添加自己的自定义属性并自行过滤...

答案 5 :(得分:0)

尽管我更喜欢并且将要使用属性方式,但是我确实以一种可能对OP有所帮助的方式使它工作。

这是一个例子:

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

这将排除所有名为“描述”的属性。如果您无法更改包含属性的类,则可以选择。同样,我更喜欢上面提到的属性方式。