gpt4 book ai didi

c# - 如何作为委托(delegate)传递属性?

转载 作者:可可西里 更新时间:2023-11-01 03:04:26 24 4
gpt4 key购买 nike

这是一个理论问题,我已经找到了解决问题的方法,这让我走上了不同的道路,但我认为这个问题仍然可能很有趣。

我能否像使用方法一样将对象属性作为委托(delegate)传递?例如:

假设我有一个加载了数据的数据读取器,每个字段的值都需要传递到不同类型的属性中,这些属性已经过 DBNull 检查。如果尝试获取单个字段,我可能会这样写:

if(!rdr["field1"].Equals(DBNull.Value)) myClass.Property1 = rdr["field1"];

但如果我有 100 个字段,那很快就会变得笨拙。有几种调用方法看起来不错:

myClass.Property = GetDefaultOrValue<string>(rdr["field1"]); //Which incidentally is the route I took

作为扩展方法也可能看起来不错:

myClass.Property = rdr["field1"].GetDefaultOrValue<string>();

或者:

SetPropertyFromDbValue<string>(myClass.Property1, rdr["field1"]); //Which is the one that I'm interested in on this theoretical level

在第二种情况下,属性需要作为委托(delegate)传递才能设置它。

所以这个问题分为两部分:

  1. 这可能吗?
  2. 那会是什么样子?

[因为这只是理论上的,VB 或 C# 的答案对我来说同样可以接受]

编辑:这里有一些巧妙的答案。谢谢大家。

最佳答案

我喜欢用表达式树来解决这个问题。每当你有一个方法需要一个“属性委托(delegate)”时,使用参数类型 Expression<Func<T, TPropertyType>> .例如:

public void SetPropertyFromDbValue<T, TProperty>(
T obj,
Expression<Func<T, TProperty>> expression,
TProperty value
)
{
MemberExpression member = (MemberExpression)expression.Body;
PropertyInfo property = (PropertyInfo)member.Member;
property.SetValue(obj, value, null);
}

这样做的好处是,gets 的语法看起来也是一样的。

public TProperty GetPropertyFromDbValue<T, TProperty>(
T obj,
Expression<Func<T, TProperty>> expression
)
{
MemberExpression member = (MemberExpression)expression.Body;
PropertyInfo property = (PropertyInfo)member.Member;
return (TProperty)property.GetValue(obj, null);
}

或者,如果你觉得懒惰:

public TProperty GetPropertyFromDbValue<T, TProperty>(
T obj,
Expression<Func<T, TProperty>> expression
)
{
return expression.Compile()(obj);
}

调用看起来像:

SetPropertyFromDbValue(myClass, o => o.Property1, reader["field1"]);
GetPropertyFromDbValue(myClass, o => o.Property1);

关于c# - 如何作为委托(delegate)传递属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3372049/

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