Исключить свойство из getType(). GetProperties()

Привет, я работаю в библиотеке классов, используя С#, и у меня есть некоторые классы с некоторыми свойствами.

Я просто хочу знать, могу ли я добавить что-то, чтобы исключить некоторые свойства формы getType(). GetProperties().

Пример того, что я хочу:

тест класса

{

   public string one { get; set; }

   public string two {get ; set;}

}

и если я сделаю это:

static void Main (строка [] args)

{

  Test t = new Test();

  Type ty = t.GetType();

  PropertyInfo[] pinfo = ty.GetProperties();

  foreach (PropertyInfo p in pinfo)

  {
      Console.WriteLine(p.Name);

  }

}

Я хочу, чтобы результат был примерно таким:

один

или только одно из свойств.

Можно ли что-то сделать? Я не знаю, есть ли какие-то модификаторы или аннотации в С#, которые позволяют мне делать то, что я хочу.

Спасибо.

Ответ 1

Методы и атрибуты расширения помогут вам:

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:

Немного более элегантная реализация 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();
    }
}

Ответ 2

Вы можете поместить пользовательский атрибут в свой тип.

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

Это не будет действительно скрыто, но оно не будет отображаться в перечислении.

Ответ 3

Я не уверен, что такое домен здесь, поэтому я выхожу на конечность...

Обычно то, что вы хотите сделать, это использовать Attribute, чтобы пометить свойства, которые нужно включить в поиск метаданных, а не наоборот.

Ответ 4

С объектом PropertyInfo вы можете проверить свойства GetCustomAttributes. Таким образом, вы можете добавлять атрибуты к своим свойствам при их объявлении, а затем, когда вы отражаетесь на свойствах, вы можете выбирать только те свойства, которые отмечены желаемыми вами атрибутами.

Конечно, если вы на самом деле хотите каким-то образом помешать кому-либо рефлексивно получать ваши свойства, это не то решение, которое вы хотите.

Изменить: Мне жаль, что вы хотите GetCustomAttributes, исправлено. Видеть это: http://msdn.microsoft.com/en-us/library/kff8s254.aspx

Ответ 5

Я не думаю, что вы можете сделать это напрямую, но вы можете добавить свои собственные атрибуты и отфильтровать их самостоятельно...