是否可以将扩展方法添加到类属性中以获取与该属性关联的属性的值?

发布于 11-29 10:53 字数 748 浏览 3 评论 0原文

我有几个类,并分配了属性。我最感兴趣的是 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();

I have several classes with attributes assigned to them. The one I'm mostly interested in is the FieldLength.MaxLength value.

/// <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; }
    }

}

I need to know if it's possible to write some kind of extension method for the properties in my class to return the MaxLength value of the FieldLength attribute?

For instance. I'd like to be able to write something like the following…

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱本泡沫多脆弱2024-12-06 10:53:45

不,这是不可能的。不过,您可以在 Users 上添加扩展方法:

public static int LastNameMaxLength(this Users user) {
    // get by reflection, return
}

No, this is not possible. You could add an extension method on Users though:

public static int LastNameMaxLength(this Users user) {
    // get by reflection, return
}
酒与心事2024-12-06 10:53:45

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

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

这样,它将出现在所有对象上(除非您指定 where T 限制),并且您拥有属性访问器的编译时安全实现,就像您将代码使用为:

user.MaxLength(u => u.LastName);

To save typing, you could further refine Jason's Extension to something like this.

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

This way it will appear on all object (unless you specify a where T restriction) and you have a compile-time safe implementation of the Property Accessor as you would use the code as:

user.MaxLength(u => u.LastName);
狠疯拽2024-12-06 10:53:45

不会。因为您建议的语法返回 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);
    }
}

No. Because the syntax you propose returns the value of the LastName property and not the property itself.

In order to retrieve and make use of the attributes, you'll need to use reflection which means you need to know the property itself.

As an idea, you could achieve this neatly by using LINQ's Expression library though to resolve the property for the object.

Example syntax you might look for:

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

Where:

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

I've found this class helpful in resolving properties from Expressions:

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);
    }
}
檐上三寸雪2024-12-06 10:53:45

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

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

并这样称呼它:

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

That's not possible in that form. The best you can manage is a method that takes a lambda expression, gets the property associated with it and then use reflection to obtain the attribute.

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

And call it like:

GetMaxLength<Users>((u)=>LastName)
对岸观火2024-12-06 10:53:45

您可以编写一个扩展方法,但它必须接受 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();

You could write an extension method, but it would have to accept a first parameter of PropertyInfo rather than string (since the string itself has no attributes.) It would look something like this:

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
}

You then get the property via reflection:

int maxLength = typeof(Users).GetProperty("LastName").GetMaxLength();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文