2011-08-12 21 views
4

我有幾個屬性分配給他們的類。我最感興趣的是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屬性值?

例如,我希望能夠寫下如下內容...

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

C#不支持屬性本身的擴展方法;你可以做的最好的做法是在屬性的返回類型上定義一個擴展方法,該方法不會實現你想要的。 – cdhowie

回答

0

號:你可以在Users添加一個擴展方法雖然。

爲了檢索和使用屬性,您需要使用反射,這意味着您需要知道屬性本身。

作爲一個想法,您可以通過使用LINQ的Expression庫來實現這一點,儘管解決該對象的屬性。

示例語法也可以查找:

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

不,這是不可能的。因爲語法你提出的回報LastName屬性的值,而不是物業本身

public static int LastNameMaxLength(this Users user) { 
    // get by reflection, return 
} 
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(); 
0

那是不可能以這種形式。您可以管理的最好方法是採用lambda表達式,獲取與其關聯的屬性,然後使用反射來獲取屬性。

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

,並調用它像:

GetMaxLength<Users>((u)=>LastName) 
2

爲了節省打字,你可以進一步細化賈森的擴展,這樣的事情。

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

這樣,它會出現在所有對象(除非你指定一個where T限制),你有一個編譯時安全的實現屬性訪問的,你將使用代碼:

user.MaxLength(u => u.LastName); 
相關問題