将字符串转换为动态对象

时间:2013-07-17 12:54:12

标签: c# dynamic

是否有直接的转换方式:

string str = "a=1,b=2,c=3";

成:

dynamic d = new { a = 1, b = 2, c = 3 };

我想我可能会编写一个分割字符串并循环结果以创建动态对象的函数。我只是想知道是否有更优雅的方式来做这件事。

4 个答案:

答案 0 :(得分:9)

我认为如果将“=”转换为“:”并用大括号包装所有内容,您将获得一个有效的JSON字符串。

然后,您可以使用JSON.NET将其反序列化为动态对象:

dynamic d = JsonConvert.DeserializeObject<dynamic>(jsonString);

你会得到你想要的东西。

答案 1 :(得分:6)

您可以使用Microsoft Roslynhere的一体化NuGet包):

class Program
{
    static void Main(string[] args)
    {
        string str = "a=1,b=2,c=3,d=\"4=four\"";
        string script = String.Format("new {{ {0} }}",str);
        var engine = new ScriptEngine();
        dynamic d = engine.CreateSession().Execute(script);
    }
}

如果你想添加更复杂的类型:

string str = "a=1,b=2,c=3,d=\"4=four\",e=Guid.NewGuid()";
...
engine.AddReference(typeof(System.Guid).Assembly);
engine.ImportNamespace("System");
...
dynamic d = engine.CreateSession().Execute(script);

根据评论中的问题,存在代码注入漏洞。如上所示添加System引用和命名空间,然后将str替换为:

string str =
    @" a=1, oops = (new Func<int>(() => { 
                Console.WriteLine(
                    ""Security incident!!! User {0}\\{1} exposed "",
                    Environment.UserDomainName,
                    Environment.UserName); 
                return 1; 
            })).Invoke() ";

答案 2 :(得分:1)

您描述的问题类似于反序列化,即从数据形式构建对象(如字符串,字节数组,流等)。希望此链接有助于:http://msdn.microsoft.com/en-us/library/vstudio/ms233843.aspx

答案 3 :(得分:1)

这是一个使用ExpandoObject自行解析后存储它的解决方案。现在它将所有值添加为string s,但您可以添加一些解析来尝试将其转换为double,int或long(您可能希望按此顺序尝试)。

static dynamic Parse(string str)
{
    IDictionary<String, Object> obj = new ExpandoObject();
    foreach (var assignment in str.Split(','))
    {
        var sections = assignment.Split('=');
        obj.Add(sections[0], sections[1]);
    }
    return obj;
}

使用它像:

dynamic d = Parse("a=1,b=2,c=3");
// d.a is "1"