2

This is in the Immediate console:

prop.GetCustomAttributes(typeof(RequiredParameterAttribute),true)

{BridgeStack.DataContracts.RequiredParameterAttribute[0]}

prop.GetCustomAttributes(typeof(RequiredParameterAttribute),true).Cast<RequiredParameterAttribute>()

{BridgeStack.DataContracts.RequiredParameterAttribute[0]} [BridgeStack.DataContracts.RequiredParameterAttribute[]]: {BridgeStack.DataContracts.RequiredParameterAttribute[0]}

prop.GetCustomAttributes(typeof(RequiredParameterAttribute),true).Cast<RequiredParameterAttribute>().Any()

false

I get the same results in the application.

prop is Site in:

public class AnswerCollectionQuery : IPagedQuery, ISiteQuery, ISortableQuery, IOrderableQuery, IFilteredQuery
{
    public int? Page { get; set; }
    public int? PageSize { get; set; }
    public string Site { get; set; }

    [AllowedSortValues(QuerySortEnum.Activity, QuerySortEnum.Creation, QuerySortEnum.Votes)]
    public QuerySortEnum? Sort { get; set; }

    public object Min { get; set; }
    public object Max { get; set; }
    public DateTime? FromDate { get; set; }
    public DateTime? ToDate { get; set; }

    public QueryOrderEnum? Order { get; set; }

    public string Filter { get; set; }
}

Site in turn comes from ISiteQuery

public interface ISiteQuery : IQuery
{
    [RequiredParameter]
    string Site { get; set; }
}

The awkward part is that the console shows the attribute, allows me to cast it, but I can't retrieve it at all, I get zero as the enumeration's length, which is why .Any() fails, too, .FirstOrDefault() returns null, .First() throws, etc.

Any explanation for this type of behavior?

PD: this works though if I decorate Site with [RequiredAttribute] in the concrete class. But I wanted to make this part of the interface.

Update for clarity:

prop comes exactly from here:

    public static IEnumerable<PropertyInfo> GetAllProperiesOfObject(object o)
    {
        const BindingFlags flags = BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance;
        PropertyInfo[] list = o.GetType().GetProperties(flags);

        return list;
    }

foreach (PropertyInfo prop in Utility.GetAllProperiesOfObject(entity))

This is the case for when prop becomes Site

bevacqua
  • 47,502
  • 56
  • 171
  • 285

1 Answers1

2

The zero is because it is returning you a zero-length typed array, meaning: it doesn't have the attribute. You can also see this with Attribute.IsDefined (which will return false).

When using implicit interface implementation, the public property on the class does not automatically gain attributes from the interface that it satisfies. To see the attributes on the interface you would need to use

typeof(ITheInterface).GetProperties()

The Site property on the interface is unrelated to the Site property on the class. If the property on the class must have attributes: add the attributes explicitly.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900