5

我有几个具有分配给它们的属性的类。我最感兴趣的是 FieldLength.MaxLength 值。

/// <summary>
/// Users
/// </summary>
[Table(Schema = "dbo", Name = "users"), Serializable]
public partial class Users
{

    /// <summary>
    /// Last name
    /// </summary>
    [Column(Name = "last_name", SqlDbType = SqlDbType.VarChar)]
    private string _LastName;
    [FieldLength(MaxLength=25), FieldNullable(IsNullable=false)]
    public string LastName
    {
        set { _LastName = value; }
        get { return _LastName; }
    }

}

我需要知道是否可以为我的类中的属性编写某种扩展方法以返回 FieldLength 属性的 MaxLength 值?

例如。我希望能够写出类似下面的东西……</p>

Users user = new Users();
int lastNameMaxLength = user.LastName.MaxLength();
4

5 回答 5

2

不,这是不可能的。您可以添加一个扩展方法Users

public static int LastNameMaxLength(this Users user) {
    // get by reflection, return
}
于 2011-08-12T01:31:56.253 回答
2

为了节省打字,您可以将 Jason 的扩展进一步细化为类似的内容。

public static void MaxLength<T>(this T obj, Expression<Func<T, object>> property)

这样,它将出现在所有对象上(除非您指定where T限制),并且您拥有 Property Accessor 的编译时安全实现,因为您将代码用作:

user.MaxLength(u => u.LastName);
于 2011-08-12T02:14:06.993 回答
0

不,因为您建议的语法返回属性的值,LastName而不是属性本身。

为了检索和使用属性,您需要使用反射,这意味着您需要了解属性本身。

作为一个想法,您可以通过使用 LINQ 的表达式库来巧妙地实现这一点,但可以解析对象的属性。

您可能会寻找的示例语法:

var lastNameMaxLength = AttributeResolver.MaxLength<Users>(u => u.LastName);

在哪里:

public class AttributeResolver
{
    public int MaxLength<T>(Expression<Func<T, object>> propertyExpression)
    {
        // Do the good stuff to get the PropertyInfo from the Expression...
        // Then get the attribute from the PropertyInfo
        // Then read the value from the attribute
    }
}

我发现这个类有助于解析表达式中的属性:

public class TypeHelper
{
    private static PropertyInfo GetPropertyInternal(LambdaExpression p)
    {
        MemberExpression memberExpression;

        if (p.Body is UnaryExpression)
        {
            UnaryExpression ue = (UnaryExpression)p.Body;
            memberExpression = (MemberExpression)ue.Operand;
        }
        else
        {
            memberExpression = (MemberExpression)p.Body;
        }
        return (PropertyInfo)(memberExpression).Member;
    }

    public static PropertyInfo GetProperty<TObject>(Expression<Func<TObject, object>> p)
    {
        return GetPropertyInternal(p);
    }
}
于 2011-08-12T01:32:47.173 回答
0

您可以编写一个扩展方法,但它必须接受第一个参数PropertyInfo而不是string(因为它string本身没有属性。)它看起来像这样:

public static int GetMaxLength(this PropertyInfo prop)
{
    // TODO: null check on prop
    var attributes = prop.GetCustomeAttributes(typeof(FieldLengthAttribute), false);
    if (attributes != null && attributes.Length > 0)
    {
        MaxLengthAttribute mla = (MaxLengthAttribute)attributes[0];
        return mla.MaxLength;
    }

    // Either throw or return an indicator that something is wrong
}

然后通过反射获得属性:

int maxLength = typeof(Users).GetProperty("LastName").GetMaxLength();
于 2011-08-12T01:36:07.083 回答
0

那种形式是不可能的。您可以管理的最好方法是采用 lambda 表达式,获取与其关联的属性,然后使用反射来获取属性。

int GetMaxLength<T>(Expression<Func<T,string>> property);

并称它为:

GetMaxLength<Users>((u)=>LastName)
于 2011-08-12T01:37:17.977 回答