gpt4 book ai didi

c# - 使用 Intellisense 和编译时检查提取属性名称以进行反射

转载 作者:可可西里 更新时间:2023-11-01 07:54:18 25 4
gpt4 key购买 nike

好的。所以我有一些代码将 winForm 上的某些控件映射到对象中的某些属性,以便在数据发生某些事情时对控件执行某些事情。一切都很好,工作正常。不是问题。问题是,为了将项目添加到映射,我调用了一个如下所示的函数:

this.AddMapping(this.myControl,myObject,"myObjectPropertyName");

我遇到的问题是,在编译时很难区分上面一行和下面一行之间的区别:

this.AddMapping(this.myControl,myObject,"myObjectPropretyName");

因为最后一个参数是一个字符串,所以没有编译时检查或任何类似的东西来强制字符串本身实际上对应于给定对象上的有效属性名称。此外,诸如 Refactor 和“Find All References”之类的东西会遗漏这种类型的引用,导致当属性本身的名称发生变化时很有趣。所以我想知道是否有一些方法可以改变函数,这样我传入的仍然是一个以某种方式表示属性名称的字符串,但编译时会检查实际值。有人说我可以用表达式树做到这一点,但我已经阅读了它们并且似乎没有看到连接。我很想做这样的事情:

this.AddMapping(this.myControl,myObject,myObject.myObjectPropertyName);

甚至

this.AddMapping(this.myControl,myObject.myObjectPropertyName);

会很甜蜜!

有什么想法吗?

最佳答案

在 3.5 中,Expression 是一种将成员名称指定为代码的方式;你可以:

public void AddMapping<TObj,TValue>(Control myControl, TObj myObject,
Expression<Func<TObj, TValue>> mapping) {...}

然后解析表达式树得到值。效率有点低,但还算不错。

示例代码:

    public void AddMapping<TSource, TValue>(
Control control,
TSource source,
Expression<Func<TSource, TValue>> mapping)
{
if (mapping.Body.NodeType != ExpressionType.MemberAccess)
{
throw new InvalidOperationException();
}
MemberExpression me = (MemberExpression)mapping.Body;
if (me.Expression != mapping.Parameters[0])
{
throw new InvalidOperationException();
}
string name = me.Member.Name;
// TODO: do something with "control", "source" and "name",
// maybe also using "me.Member"
}

调用:

    AddMapping(myControl, foo, f => f.Bar);

关于c# - 使用 Intellisense 和编译时检查提取属性名称以进行反射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/795208/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com