【问题标题】:How to create own dynamic type or dynamic object in C#?如何在 C# 中创建自己的动态类型或动态对象?
【发布时间】:2012-10-03 13:17:17
【问题描述】:

例如,ControllerBase 类的 ViewBag 属性,我们可以动态地获取/设置值并向该对象添加任意数量的附加字段或属性,这很酷。除了 MVC 应用程序和其他类型的应用程序中的 Controller 类之外,我想使用类似的东西。当我尝试创建dynamic 对象并将其属性设置如下:

1. dynamic MyDynamic = new { A="a" };
2. MyDynamic.A = "asd";
3. Console.WriteLine(MyDynamic.A);

我有 RuntimeBinderException 和消息 Property or indexer 'f__AnonymousType0.A' cannot be assigned to -- it is read only 在第 2 行。另外,我怀疑它不完全我在找什么。也许有一些课程可以让我做类似的事情:

??? MyDynamic = new ???();
MyDynamic.A = "A";
MyDynamic.B = "B";
MyDynamic.C = DateTime.Now;
MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;

具有动态添加和设置属性。

【问题讨论】:

    标签: c# dynamic viewbag


    【解决方案1】:
    dynamic MyDynamic = new System.Dynamic.ExpandoObject();
    MyDynamic.A = "A";
    MyDynamic.B = "B";
    MyDynamic.C = "C";
    MyDynamic.Number = 12;
    MyDynamic.MyMethod = new Func<int>(() => 
    { 
        return 55; 
    });
    Console.WriteLine(MyDynamic.MyMethod());
    

    阅读有关ExpandoObject class 的更多信息以及更多示例:表示一个对象,其成员可以在运行时动态添加和删除。

    【讨论】:

    • 请在 Visual Studio UserVoice 中投票支持此功能。
    【解决方案2】:

    我最近需要更进一步,即根据用户定义的条目在动态对象中添加属性,使其自身动态化。这里的示例以及来自Microsoft's ExpandoObject documentation 的示例并没有专门解决动态添加属性的问题,但是可以从您如何枚举和删除属性中推测出来。无论如何,我认为这可能对某人有帮助。这是一个极其简化的版本,说明如何将真正的动态属性添加到 ExpandoObject(忽略关键字和其他处理):

    // my pretend dataset
    List<string> fields = new List<string>();
    // my 'columns'
    fields.Add("this_thing");
    fields.Add("that_thing");
    fields.Add("the_other");
    
    dynamic exo = new System.Dynamic.ExpandoObject();
    
    foreach (string field in fields)
    {
        ((IDictionary<String, Object>)exo).Add(field, field + "_data");
    }
    
    // output - from Json.Net NuGet package
    textBox1.Text = Newtonsoft.Json.JsonConvert.SerializeObject(exo);
    

    【讨论】:

    • 有人知道为什么我们必须输入 cast 才能访问Add 方法吗?这对我来说似乎很奇怪。
    • 这是因为 ExpandoObject 没有公开直接的 Add 方法。如果您尝试使用 .Add,它会将该语句视为您想要向对象添加“添加”成员。您必须公开底层数据结构,基本上是访问 Dictionary 接口,才能访问其 Add 方法。这也是删除一个成员或任何其他在 Dictionary 中提供但未在 ExpandoObject 本身中公开的情况。较新的文档似乎更好地解释了这一要求:docs.microsoft.com/en-us/dotnet/api/…
    【解决方案3】:

    ExpandoObject 是你要找的。​​p>

    dynamic MyDynamic = new ExpandoObject(); // note, the type MUST be dynamic to use dynamic invoking.
    MyDynamic.A = "A";
    MyDynamic.B = "B";
    MyDynamic.C = "C";
    MyDynamic.TheAnswerToLifeTheUniverseAndEverything = 42;
    

    【讨论】:

      【解决方案4】:
      dynamic myDynamic = new { PropertyOne = true, PropertyTwo = false};
      

      【讨论】:

        【解决方案5】:
        var data = new { studentId = 1, StudentName = "abc" };  
        

        或存在价值

        var data = new { studentId, StudentName };
        

        【讨论】:

        • 谢谢,正是我要找的东西
        【解决方案6】:

        您可以使用位于System.Dynamic 命名空间中的ExpandoObject Class

        dynamic MyDynamic = new ExpandoObject();
        MyDynamic.A = "A";
        MyDynamic.B = "B";
        MyDynamic.C = "C";
        MyDynamic.SomeProperty = SomeValue
        MyDynamic.number = 10;
        MyDynamic.Increment = (Action)(() => { MyDynamic.number++; });
        

        更多信息可以在 ExpandoObject MSDN

        【讨论】:

          【解决方案7】:
          dynamic MyDynamic = new ExpandoObject();
          

          【讨论】:

            猜你喜欢
            • 2018-05-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-29
            • 2014-06-03
            • 2013-12-16
            • 2013-04-09
            相关资源
            最近更新 更多