- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想在编译时不知道对象类型的情况下设置对象的属性值;我希望它快(即不要每次都使用反射);我知道属性名称和类型。
最快的方法 (afaik) 是使用委托(delegate);所以这就是我到目前为止所拥有的:
class User // this is an example.. Assume I don't know which type this is.
{
public string Name {get;set;}
}
public static Action<object, object> CreatePropertySetter(Type targetType, string propertyName)
{
ParameterExpression targetObjParamExpr = Expression.Parameter(targetType);
ParameterExpression valueParamExpr = Expression.Parameter(targetType.GetProperty(propertyName).PropertyType);
MemberExpression propertyExpr = Expression.Property(targetObjParamExpr, propertyName);
BinaryExpression assignExpr = Expression.Assign(targetObjParamExpr, valueParamExpr);
Action<object, object> result = Expression.Lambda<Action<object, object>>(assignExpr, targetObjParamExpr, valueParamExpr).Compile();
return result;
}
然后我会打这个电话:
User user = new User();
var userNameSetter = CreatePropertySetter(user.GetType(), "Name");
userNameSetter(user, "Bob");
但是,它不喜欢我传递 User 类型对象而不是 Object 的事实,并且失败并显示“'User' 类型的 ParameterExpression 不能用于'System.Object 类型的委托(delegate)参数”。
我是表达式树的新手,所以在这里有点迷路。为什么不能将 User 转换为 object ?我需要在某处类型转换吗?
“ Action ”看起来也不太好;只返回一个接受参数(用户用户,字符串属性值)的委托(delegate)会更好。同样,不确定如何实现。实际上,我已经尝试过使用 Delegate.CreateDelegate,但它使用 .Invoke() 方法调用,这很慢(这是唯一的方法吗?);与 Expression.Lambda(非泛型)相同。
有什么想法吗?
此外,是否有关于表达式树的良好(比 msdn 更好)的文档? msdn版本确实缺乏细节。
最佳答案
如果你想使用Expression,那么:Convert
...
static void Main()
{
var setter = CreatePropertySetter(typeof (User), "Name");
var obj = new User();
setter(obj, "Fred");
}
public static Action<object, object> CreatePropertySetter(Type targetType, string propertyName)
{
var target = Expression.Parameter(typeof (object), "obj");
var value = Expression.Parameter(typeof (object), "value");
var property = targetType.GetProperty(propertyName);
var body = Expression.Assign(
Expression.Property(Expression.Convert(target, property.DeclaringType), property),
Expression.Convert(value, property.PropertyType));
var lambda = Expression.Lambda<Action<object, object>>(body, target, value);
return lambda.Compile();
}
但是!你可能想看看 FastMember (也可在 NuGet 上获得),它非常方便地为您包装了所有(并使用原始 IL 来实现愚蠢的疯狂)。
如果你想使用有类型的委托(delegate),你需要提前知道类型。如果您知道类型,您可以添加一些泛型:
static void Main()
{
var setter = CreatePropertySetter<User,string>("Name");
var obj = new User();
setter(obj, "Fred");
}
public static Action<TType, TValue> CreatePropertySetter<TType, TValue>(string propertyName)
{
var target = Expression.Parameter(typeof (TType), "obj");
var value = Expression.Parameter(typeof (TValue), "value");
var property = typeof(TType).GetProperty(propertyName);
var body = Expression.Assign(
Expression.Property(target, property),
value);
var lambda = Expression.Lambda<Action<TType, TValue>>(body, target, value);
return lambda.Compile();
}
关于c# - 在编译时不知道目标类型的情况下设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10760139/
我是 Java 新手,这是我的代码, if( a.name == b.name && a.displayname == b.displayname && a.linknam
在下面的场景中,我有一个 bool 值。根据结果,我调用完全相同的函数,唯一的区别是参数的数量。 var myBoolean = ... if (myBoolean) { retrieve
我是一名研究 C++ 的 C 开发人员: 我是否正确理解如果我抛出异常然后堆栈将展开直到找到第一个异常处理程序?是否可以在不展开的情况下在任何 throw 上打开调试器(即不离开声明它的范围或任何更高
在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题: struct Base { // some
我正在尝试用 C# 扩展给定的代码,但由于缺乏编程经验,我有点陷入困境。 使用 Visual Studio 社区,我尝试通过控制台读出 CPU 核心温度。该代码使用开关/外壳来查找传感器的特定名称(即
这可能是一个哲学问题。 假设您正在向页面发出 AJAX 请求(这是使用 Prototype): new Ajax.Request('target.asp', { method:"post", pa
我有以下 HTML 代码,我无法在所有浏览器中正常工作: 我试图在移动到
我对 Swift 很陌生。我如何从 addPin 函数中检索注释并能够在我的 addLocation 操作 (buttonPressed) 中使用它。我正在尝试使用压力触摸在 map 上添加图钉,在两
我设置了一个详细 View ,我是否有几个 Nib 文件根据在 Root View Controller 的表中选择的项目来加载。 我发现,对于 Nibs 的类,永远不会调用 viewDidUnloa
我需要动态访问 json 文件并使用以下代码。在本例中,“bpicsel”和“temp”是变量。最终结果类似于“data[0].extit1” var title="data["+bpicsel+"]
我需要使用第三方 WCF 服务。我已经在我的证书存储中配置了所需的证书,但是在调用 WCF 服务时出现以下异常。 向 https://XXXX.com/AHSharedServices/Custome
在几个 SO 答案(1、2)中,建议如果存在冲突则不应触发 INSERT 触发器,ON CONFLICT DO NOTHING 在触发语句中。也许我理解错了,但在我的实验中似乎并非如此。 这是我的 S
如果进行修改,则会给出org.hibernate.NonUniqueObjectException。在我的 BidderBO 类(class)中 @Override @Transactional(pr
我使用 indexOf() 方法来精细地查找数组中的对象。 直到此刻我查了一些资料,发现代码应该无法正常工作。 我在reducer中尝试了上面的代码,它成功了 let tmp = state.find
假设我有以下表格: CREATE TABLE Game ( GameID INT UNSIGNED NOT NULL, GameType TINYINT UNSIGNED NOT NU
代码: Alamofire.request(URL(string: imageUrl)!).downloadProgress(closure: { (progress) in
我是一名优秀的程序员,十分优秀!