动态创建C#类或对象

6

我有这个结构。

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”类型。我查阅了{{link1:“动态添加C#运行时属性”}}和{{link2:“如何在C#中动态创建类?”}},但这些链接中的答案没有被引用为返回值或引用到另一个类。我该怎么做?

6
如果您解释为什么需要那个,有人可能会建议更好的方法来解决问题,而不是在运行时添加属性。 - Evk
@Evk 我认为没有必要再考虑这个问题,谢谢。 - Muhammet Can TONBUL
2个回答

2
你可以动态地创建继承 Foo 类的类,并添加任意额外的属性。因此,你可以将这些动态类的实例添加到 List<Foo> 中。
为了做到这一点,可以生成以下代码字符串:
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<Foo> 中,并将其转换为 dynamic 来访问动态属性:

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
@kuldeep,可以从库中使用这个类。例如,Castle.DynamicProxy和广泛使用的Moq包使用类似的模式,在运行时自动实现接口。 - stop-cran
这方面有教程或示例吗?我在谷歌上找不到任何东西。我可以即时创建一个包含我的模型的类,但我现在不确定如何使用这些模型类。 - kuldeep
@kuldeep 这取决于你的目的。通常情况下,从一些在编译时已知的接口继承“即时”类是一个好主意。然后,您可以在代码中将它们转换为该接口,并使用其功能。例如,前面提到的 Moq 包有一个名为 Mock<T> 的类,它能够即时实现 T 的虚拟方法。它还有一个类型为 TObject 属性,表示具有重写 T 成员的实现。 - stop-cran
用例是我想使用一个自定义序列化库,因为它包括很多样板代码,可以处理诸如Bigendian、numberformatting等问题。现在到目前为止,生成类的过程是在编译时完成的,我们希望能够通过json文件动态地完成它。有两个选择,要么使用动态对象进行动态解析,要么使用代码生成(基于json结构)来转储模型类,并使用现有的序列化器库进行操作,在前一种情况下,我们无法使用这个自定义序列化库,因此出现了这个问题。 - kuldeep
@kuldeep 在这种情况下,可以通过自定义构建步骤从 JSON 生成 C# 类的代码,例如像 gRPC 中所做的那样 - C# 类是从 protobuf 生成的。在 .Net 5 中引入了一种新的强大方式 - 源代码生成器 - stop-cran

0

为什么不直接使用 字典 呢?

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 };
}

在运行时为一个类添加属性是不可能的。

我正在使用Firstclass,像这样在GetFoo函数中 typeof(FirstClass)。因此,在FirstClass中,FooList变量List<Foo>似乎是默认的Foo类类型。@Rainman - Muhammet Can TONBUL
看一下这篇文章可能更好。你想通过动态反序列化 XML。https://dev59.com/6GYr5IYBdhLWcg3waJZT - lucky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接