You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core中如何通过变量名动态访问及赋值类属性?

没问题!在C#里要实现这种通过字符串动态访问、设置对象属性的需求,我们一般用**反射(Reflection)**来搞定,下面给你一步步拆解具体实现:

一、动态获取属性值

首先我们可以借助System.Reflection命名空间里的PropertyInfo类来实现。先看完整的代码示例:

using System.Reflection;

public class Student 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
}

// 封装一个通用的动态获取属性值方法
public static object GetPropertyValue(object obj, string propertyName)
{
    // 获取目标对象的类型
    Type objType = obj.GetType();
    
    // 查找指定的公共实例属性(这里的BindingFlags很重要,确保能正确找到属性)
    PropertyInfo property = objType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
    
    if (property == null)
    {
        throw new ArgumentException($"找不到属性:{propertyName}(类型:{objType.Name})");
    }
    
    // 获取并返回属性值
    return property.GetValue(obj);
}

// 使用示例
Student s = new Student { Name = "Alice", Age = 20 };
string targetProperty = "Age";
var ageValue = GetPropertyValue(s, targetProperty); // 返回20(类型为object,可按需强转:(int)ageValue)

这里要注意:

  • 必须引用System.Reflection命名空间;
  • BindingFlags.Public | BindingFlags.Instance是为了明确查找公共的实例属性,如果你的属性是非公共的,需要调整绑定标志;
  • 返回值是object类型,实际使用时可以根据属性的真实类型进行强转。
二、动态设置属性值

同理,我们可以用PropertyInfo.SetValue()方法来实现动态赋值,甚至可以额外处理类型转换的场景(比如把字符串转成int):

// 封装通用的动态设置属性值方法
public static void SetPropertyValue(object obj, string propertyName, object value)
{
    Type objType = obj.GetType();
    PropertyInfo property = objType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
    
    if (property == null)
    {
        throw new ArgumentException($"找不到属性:{propertyName}(类型:{objType.Name})");
    }
    
    // 可选:自动转换值的类型,适配属性类型
    try
    {
        value = Convert.ChangeType(value, property.PropertyType);
    }
    catch (InvalidCastException ex)
    {
        throw new ArgumentException($"无法将值 {value} 转换为属性 {propertyName} 的类型 {property.PropertyType}", ex);
    }
    
    // 设置属性值
    property.SetValue(obj, value);
}

// 使用示例
Student s = new Student { Name = "Bob", Age = 25 };
string targetProperty = "Age";
SetPropertyValue(s, targetProperty, 35); // 此时s.Age变为35

// 也支持跨类型转换(比如字符串转int)
SetPropertyValue(s, targetProperty, "40"); // s.Age会被设置为40

这个方法里加了类型转换的逻辑,能处理一些常见的类型不匹配场景,比如用户传入字符串类型的数字,自动转成int赋值给Age属性。

三、性能优化小技巧(可选)

反射虽然好用,但如果是高频调用的场景,可能会有一定的性能开销。这时候可以用**表达式树(Expression Tree)**缓存获取/设置属性的委托,性能接近直接调用属性:

using System.Linq.Expressions;

// 缓存获取属性的委托
private static readonly Dictionary<(Type, string), Func<object, object>> _getterCache = new Dictionary<(Type, string), Func<object, object>>();

public static object GetPropertyValueFast(object obj, string propertyName)
{
    var cacheKey = (obj.GetType(), propertyName);
    
    // 先从缓存取,没有则编译表达式树
    if (!_getterCache.TryGetValue(cacheKey, out var getter))
    {
        var param = Expression.Parameter(typeof(object), "obj");
        var castObj = Expression.Convert(param, cacheKey.Item1);
        var property = Expression.Property(castObj, propertyName);
        var castResult = Expression.Convert(property, typeof(object));
        
        getter = Expression.Lambda<Func<object, object>>(castResult, param).Compile();
        _getterCache[cacheKey] = getter;
    }
    
    return getter(obj);
}

设置属性的委托缓存逻辑类似,这里就不重复写了。这种方式第一次调用会编译表达式,之后直接调用缓存的委托,性能提升很明显。

内容的提问来源于stack exchange,提问作者Rushikesh Sane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:43:29