【问题标题】:Dynamically Create C# Class or Object动态创建 C# 类或对象
【发布时间】:2018-05-25 20:35:50
【问题描述】:

我有这个结构。

public class FirstClass
{
   public List<Foo> FooList{ get; set; }
}

public class Foo{
   //Ex:
   //public string Name{ get; set; }  
}

public List<Foo> GetFoo(){
//I'm use Firstclass like this here typeof(FirstClass);
//I want create here dynamic property for Foo class.
}

我的问题是,我想从“GetFoo()”函数为“Foo”类创建属性。同时,该函数返回“List”“Foo”类型。我正在研究"Dynamically Add C# Properties at Runtime""How to dynamically create a class in C#?",但这些链接中的答案没有被引用为返回值或被引用到另一个类。我该怎么做?

【问题讨论】:

  • 如果您描述了为什么需要它,有人可能会建议一种更好的方法来解决问题,而不是在运行时添加属性。
  • @Evk 我认为没有必要再次考虑这个问题,谢谢。

标签: c# dynamic properties


【解决方案1】:

您可以动态创建继承Foo 的类,以及任何其他属性。因此,您可以将这些动态类的实例添加到List&lt;Foo&gt;

为此,可以生成如下代码字符串:

var bar1Code = @"
public class Bar1 : Foo
{
    public Bar1(int value)
    {
        NewProperty = value;
    }
    public int NewProperty {get; set; }
}
";

然后使用CSharpCodeProvider进行编译:

var compilerResults = new CSharpCodeProvider()
    .CompileAssemblyFromSource(
        new CompilerParameters
        {
            GenerateInMemory = true,
            ReferencedAssemblies =
            {
                "System.dll",
                Assembly.GetExecutingAssembly().Location
            }
        },
        bar1Code);

然后可以创建Bar1 的一个实例,将其添加到List&lt;Foo&gt;,例如将其转换为动态以访问动态属性:

var bar1Type = compilerResults.CompiledAssembly.GetType("Bar1");
var bar2Type = compilerResults.CompiledAssembly.GetType("Bar2"); // By analogy

var firstClass = new FirstClass
{
    FooList = new List<Foo>
    {
        (Foo)Activator.CreateInstance(bar1Type, 56),
        (Foo)Activator.CreateInstance(bar2Type, ...)
    }
};

var dynamicFoo = (dynamic)firstClass.FooList[0];
int i = dynamicFoo.NewProperty; // should be 56

【讨论】:

  • 如何在运行时使用这样的类?例如,如果我有一个需要访问此类的库,它不会给出编译错误吗?
  • @kuldeep 可以从库中使用此类。例如 Castle.DynamicProxy 和广泛使用的 Moq 包使用类似的模式在运行时自动实现接口。
  • 有这方面的教程或示例吗?我很难在谷歌上找到任何东西。我可以动态创建一个包含我的模型的类,但我现在不确定如何使用这些模型类
  • @kuldeep 这取决于你的目的。一般来说,从编译时已知的某些接口继承“on-the-fly”类是一个好主意。然后可以将它们转换为代码中的接口,从而使用它们的功能。例如,上述 Moq 包具有类 Mock&lt;T&gt;,它能够即时实现 T 的虚拟方法。它还有一个Object 类型为T 的属性,它表示具有T 覆盖成员的实现。
  • 用例是我想使用自定义序列化库,因为它包含大量样板代码,用于处理诸如 Bigendian、数字格式化等问题。到目前为止,生成类的过程是在编译时,我们希望能够通过 json 文件动态地完成它。有两种选择,要么通过动态对象使用动态解析,要么使用代码生成(基于 json 结构)转储模型类并为此使用现有的序列化程序库,显然在前面的情况下我们不能使用这个自定义序列化程序库,因此问题。
【解决方案2】:

你为什么不直接使用Dictionary

public class Foo
{
    public Dictionary<string, object> Properties;

    public Foo()
    {
        Properties = new Dictionary<string, object>();
    }
}
public List<Foo> GetFoo()
{
    var item = new Foo();
    item.Properties.Add("Name","Sample");
    item.Properties.Add("OtherName", "Sample");
    return new List<Foo>{ item };
}

在运行时为类添加属性,无法执行。

【讨论】:

  • 我在 GetFoo 函数上使用 Firstclass 之类的 typeof(FirstClass)。所以在 FirstClass 中,FooList 变量 List 似乎是默认的 Foo 类类型。 @雨人
  • 看看这篇文章可能会更好。您想通过动态反序列化 xml。 stackoverflow.com/questions/13704752/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多