How do I define a property to read an attribute from, without instantionating an object?

前端 未结 5 1415
名媛妹妹
名媛妹妹 2021-01-23 10:00

Suppose I have:

class Person
{
[ColumnAttribute(\"ID\"]
    public int Id;
[ColumnAttribute(\"Name\"]
public string Name;
[ColumnAttribute(\"DateOfBirth\"]
    p         


        
相关标签:
5条回答
  • 2021-01-23 10:43

    Is there a specific reason to force ordering on the GetAllByAge() method itself? Why not just sort it once you get it back? Does the order by logic need to happen server side? I would return a List<Person> (which you mentioned doing yourself) and use LINQ to order the set as needed, unless I had a really good reason not to:

    Dal.Person.GetAllByAge(25).OrderBy(p => p.BirthDate);
    
    0 讨论(0)
  • 2021-01-23 10:58

    Yep, I defined an extension method, to make it a bit easier, so i can just call typeof(Person).GetAttributes<CollumnAttribute>():

            /// <summary>
        /// Loads the configuration from assembly attributes
        /// </summary>
        /// <typeparam name="T">The type of the custom attribute to find.</typeparam>
        /// <param name="typeWithAttributes">The calling assembly to search.</param>
        /// <returns>An enumeration of attributes of type T that were found.</returns>
        public static IEnumerable<T> GetAttributes<T>(this Type typeWithAttributes)
            where T : Attribute
        {
            // Try to find the configuration attribute for the default logger if it exists
            object[] configAttributes = Attribute.GetCustomAttributes(typeWithAttributes,
                typeof(T), false);
    
            // get just the first one
            if (configAttributes != null && configAttributes.Length > 0)
            {
                foreach (T attribute in configAttributes)
                {
                    yield return attribute;
                }
            }
        }
    
    0 讨论(0)
  • 2021-01-23 11:01

    This is definitely doable without instantiating a Person object. You'll want to use Reflection to access the attribute, specifically the GetCustomAttributes method.

    Here's an article for reference.

    Your end result may end up looking something like this:

    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(typeof(Person));  // Reflection.
    
    0 讨论(0)
  • 2021-01-23 11:02

    In addition to Pete M's answer you could pass the Func<T1,T2> used in IEnumerable<T>.OrderBy into your method, and order within your method

    public IEnumerable<Person> GetAllByAge<T>(int age, Func<Person,T> orderBy)
    {
       var people = ... (get your collection of 'age' aged people here)
       return people.OrderBy(orderBy);
    }
    

    Usage would then be Dal.Person.GetAllByAge(25,p => p.BirthDate)

    0 讨论(0)
  • 2021-01-23 11:04

    Attributes don't allow lambdas as arguments, so p => p.BirthDate unfortunately isn't possible. In a similar scenario I used enums to link things together.

    This worked just fine for my purposes, but still results in some code duplication (being the enum declaration). This does however solve the problem of string literals, and you can now safely refactor your code.

    0 讨论(0)
提交回复
热议问题