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

C#中ExpandoObject是否有实例访问器?如何添加全名获取方法?

你的现有实现完全没问题,不过确实有几种其他方式能实现这个需求,每种各有适用场景,我给你梳理一下:

1. 显式转换为字典,减少闭包依赖

你可以利用ExpandoObject本身实现了IDictionary<string, object>接口的特性,直接从字典中读取属性值。这种写法虽然还是用到了外部的obj变量,但逻辑更清晰,也能避免闭包可能带来的意外(比如后续obj被重新赋值为其他对象的情况):

dynamic obj = new ExpandoObject();
obj.FirstName = "John";
obj.LastName = "Doe";

obj.GetFullName = new Func<string>(() => 
{
    var self = (IDictionary<string, object>)obj;
    return $"{self["FirstName"]} {self["LastName"]}";
});

2. 用扩展方法复用逻辑

如果你的多个ExpandoObject实例都需要GetFullName方法,用扩展方法会更高效,不需要给每个实例单独绑定方法:

public static class ExpandoExtensions
{
    public static string GetFullName(this ExpandoObject expando)
    {
        var properties = (IDictionary<string, object>)expando;
        if (properties.TryGetValue("FirstName", out var firstName) && 
            properties.TryGetValue("LastName", out var lastName))
        {
            return $"{firstName} {lastName}";
        }
        return string.Empty; // 或者根据需求抛出异常
    }
}

// 使用起来很简单:
dynamic obj = new ExpandoObject();
obj.FirstName = "John";
obj.LastName = "Doe";
string fullName = obj.GetFullName();

3. 自定义动态对象(改用DynamicObject)

如果你的场景需要更复杂的动态行为,而不只是临时加属性和方法,可以继承DynamicObject实现自己的动态类型,这样就能在方法里直接访问实例的属性:

public class Person : DynamicObject
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
    {
        if (binder.Name == "GetFullName" && args.Length == 0)
        {
            result = $"{FirstName} {LastName}";
            return true;
        }
        return base.TryInvokeMember(binder, args, out result);
    }
}

// 使用方式:
dynamic obj = new Person();
obj.FirstName = "John";
obj.LastName = "Doe";
string fullName = obj.GetFullName();

关于你原始的写法

其实你的原始写法是最简洁的,特别适合单个临时动态对象的场景。闭包捕获obj在这个场景下几乎不会有问题——除非你后续会把obj重新赋值为另一个对象,否则完全可以放心使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:54:35