更新泛型类的泛型属性?

发布于 2024-10-14 06:32:01 字数 369 浏览 3 评论 0原文

我对 C# 泛型类很陌生,所以我不知道我们是否可以动态更新泛型类的泛型属性?

假设我有一个类,

A { long id; long count; }

我们可以编写一个扩展来将给定属性更新 1 吗?

A.AddOne(a => a.id); will change A {id=1, count=1} to A {id=2, count=1}

and

A.AddOne(a => a.count); will change A {id=1, count=1} to A {id=1, count=2}

如有任何帮助,我们将不胜感激!

I'm quite new at C# Generic Classes so I don't know if we can update the generic property of a generic class dynamically?

Let say I have a class

A { long id; long count; }

Can we write an extension that update the given property by 1 so

A.AddOne(a => a.id); will change A {id=1, count=1} to A {id=2, count=1}

and

A.AddOne(a => a.count); will change A {id=1, count=1} to A {id=1, count=2}

Any helps would be appreciated!

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

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

发布评论

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

评论(1

梦中的蝴蝶 2024-10-21 06:32:01

如果我正确理解您的问题,您希望能够通过为 AddOne 方法提供 lambda 表达式来声明要更新的属性。在这种情况下,这是可能的——您可以编写一个扩展方法,该方法采用 Expression,从此表达式中检索属性访问表达式,并使用 Reflection 更新 上的该属性一个对象。

以下是上述内容的一个非常粗略的原型:

public static void AddOne<S,T>(this S x, Expression<Func<S,T>> expr)
{
    if (expr.Body.NodeType != ExpressionType.MemberAccess)
        throw new InvalidOperationException();

    MemberExpression memberExpr = expr.Body as MemberExpression;
    switch (memberExpr.Member.MemberType)
    {
        case MemberTypes.Field:
            {
                FieldInfo field = memberExpr.Member as FieldInfo;
                ulong value = Convert.ToUInt64(field.GetValue(x));
                ++value;
                field.SetValue(x, Convert.ChangeType(value, field.FieldType));
                break;
            }
        case MemberTypes.Property:
            {
                PropertyInfo prop = memberExpr.Member as PropertyInfo;
                ulong value = Convert.ToUInt64(prop.GetValue(x, null));
                ++value;
                prop.SetValue(x, Convert.ChangeType(value, prop.PropertyType), null);
                break;
            }
        default:
            throw new InvalidOperationException();
    }
}

If I understand your question correctly, you want to be able to declare which property to update by giving the AddOne method a lambda expression. In this case, it's possible -- you can write an extension method that takes an Expression<T>, retrieves from this expression the property access expression, and uses Reflection to update that property on the A object.

The following is a very rough prototype of the above:

public static void AddOne<S,T>(this S x, Expression<Func<S,T>> expr)
{
    if (expr.Body.NodeType != ExpressionType.MemberAccess)
        throw new InvalidOperationException();

    MemberExpression memberExpr = expr.Body as MemberExpression;
    switch (memberExpr.Member.MemberType)
    {
        case MemberTypes.Field:
            {
                FieldInfo field = memberExpr.Member as FieldInfo;
                ulong value = Convert.ToUInt64(field.GetValue(x));
                ++value;
                field.SetValue(x, Convert.ChangeType(value, field.FieldType));
                break;
            }
        case MemberTypes.Property:
            {
                PropertyInfo prop = memberExpr.Member as PropertyInfo;
                ulong value = Convert.ToUInt64(prop.GetValue(x, null));
                ++value;
                prop.SetValue(x, Convert.ChangeType(value, prop.PropertyType), null);
                break;
            }
        default:
            throw new InvalidOperationException();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文