.NET 中的自定义对象

发布于 2024-10-04 09:22:40 字数 106 浏览 0 评论 0原文

我有一个对象数组,其中包含各种数据,如 int、string、bool。我需要从对象中获取单独的记录。

我需要将它们存储在一个类中。

我知道我必须使用泛型,该怎么做?

I have an array of objects which contains various kinds of data in it, like int, string, bool. I need to get the individual records from the object.

I need to store them in a class.

I know I have to use generics, how to do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

肩上的翅膀 2024-10-11 09:22:40

您需要创建一个具有所需属性的类(例如,MyRecord),然后创建一个通用的List 实例来保存类实例。

You need to make a class (eg, MyRecord) with the properties you need, then make a generic List<MyRecord> instance to hold the class instances.

错爱 2024-10-11 09:22:40

泛型对你不起作用,因为它们只是编译器的魔法。您可以根据需要查看 DynamicObject 或 ExpandoObject。

或者,您也可以构建动态对象。查看 System.CodeDom 命名空间。这是一个例子

public class DynamicCodeCompiler
{
    public static Type CompileCode(string code, string typeName)
    {
        var compiler = CodeDomProvider.CreateProvider("c#");
        var compilerResults = compiler.CompileAssemblyFromSource(new CompilerParameters(), code);
        if (compilerResults.Errors.HasErrors) return null;
        return compilerResults.CompiledAssembly.GetType(typeName);
    }

    public static Type CreateClass(string nameSpaceName, string className, IDictionary<string, Type> properties)
    {
        var imports = new CodeNamespaceImportCollection();
        foreach (var value in properties.Values)
        {
            imports.Add(new CodeNamespaceImport(value.Namespace));
        }
        imports.Add(new CodeNamespaceImport("System"));

        var @class = new CodeTypeDeclaration(className)
                         {
                             IsClass = true
                         };
        foreach (var propertyDefinition in properties)
        {
            var backingField = CreateBackingField(propertyDefinition.Key, propertyDefinition.Value);
            @class.Members.Add(backingField);
            var property = new CodeMemberProperty();
            property.Attributes = MemberAttributes.Public;
            property.Name = propertyDefinition.Key;
            property.Type = new CodeTypeReference(propertyDefinition.Value);
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(backingField.Name)));
            property.SetStatements.Add(new CodeAssignStatement(new CodeSnippetExpression(backingField.Name),
                new CodePropertySetValueReferenceExpression()));
            @class.Members.Add(property);
        }

        var nameSpace = new CodeNamespace(nameSpaceName);
        nameSpace.Types.Add(@class);
        var assembly = new CodeCompileUnit();
        //Add the namespace to the assembly.
        assembly.Namespaces.Add(nameSpace);
        var compilerParameters = new CompilerParameters(new[] { "mscorlib.dll", "System.dll" })
                                     {GenerateInMemory = true};
        //compilerParameters.ReferencedAssemblies.Add("System.dll");

        var compiler = CodeDomProvider.CreateProvider("c#");
        var compilerResults = compiler.CompileAssemblyFromDom(compilerParameters, assembly);
        if (compilerResults.Errors.HasErrors)
        {
            foreach (var error in compilerResults.Errors)
            {
                Console.WriteLine(error);
            }
            return null;
        }
        var codeText = new StringWriter();
        compiler.GenerateCodeFromNamespace(nameSpace, new IndentedTextWriter(codeText), new CodeGeneratorOptions());
        return compilerResults.CompiledAssembly.GetType(string.Format("{0}.{1}", nameSpaceName, className));
    }

    private static CodeMemberField CreateBackingField(string name, Type type)
    {
        return new CodeMemberField
                   {
                       Attributes = MemberAttributes.Private,
                       Name = string.Format("_{0}", name),
                       Type = new CodeTypeReference(type)
                   };
    }
}

Generics wouldn't work for you as they are just compiler magic. You can look at DynamicObject or ExpandoObject for what you need.

Alternatively you can build a dynamic object as well. Look at System.CodeDom namespace. Here's an example

public class DynamicCodeCompiler
{
    public static Type CompileCode(string code, string typeName)
    {
        var compiler = CodeDomProvider.CreateProvider("c#");
        var compilerResults = compiler.CompileAssemblyFromSource(new CompilerParameters(), code);
        if (compilerResults.Errors.HasErrors) return null;
        return compilerResults.CompiledAssembly.GetType(typeName);
    }

    public static Type CreateClass(string nameSpaceName, string className, IDictionary<string, Type> properties)
    {
        var imports = new CodeNamespaceImportCollection();
        foreach (var value in properties.Values)
        {
            imports.Add(new CodeNamespaceImport(value.Namespace));
        }
        imports.Add(new CodeNamespaceImport("System"));

        var @class = new CodeTypeDeclaration(className)
                         {
                             IsClass = true
                         };
        foreach (var propertyDefinition in properties)
        {
            var backingField = CreateBackingField(propertyDefinition.Key, propertyDefinition.Value);
            @class.Members.Add(backingField);
            var property = new CodeMemberProperty();
            property.Attributes = MemberAttributes.Public;
            property.Name = propertyDefinition.Key;
            property.Type = new CodeTypeReference(propertyDefinition.Value);
            property.GetStatements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(backingField.Name)));
            property.SetStatements.Add(new CodeAssignStatement(new CodeSnippetExpression(backingField.Name),
                new CodePropertySetValueReferenceExpression()));
            @class.Members.Add(property);
        }

        var nameSpace = new CodeNamespace(nameSpaceName);
        nameSpace.Types.Add(@class);
        var assembly = new CodeCompileUnit();
        //Add the namespace to the assembly.
        assembly.Namespaces.Add(nameSpace);
        var compilerParameters = new CompilerParameters(new[] { "mscorlib.dll", "System.dll" })
                                     {GenerateInMemory = true};
        //compilerParameters.ReferencedAssemblies.Add("System.dll");

        var compiler = CodeDomProvider.CreateProvider("c#");
        var compilerResults = compiler.CompileAssemblyFromDom(compilerParameters, assembly);
        if (compilerResults.Errors.HasErrors)
        {
            foreach (var error in compilerResults.Errors)
            {
                Console.WriteLine(error);
            }
            return null;
        }
        var codeText = new StringWriter();
        compiler.GenerateCodeFromNamespace(nameSpace, new IndentedTextWriter(codeText), new CodeGeneratorOptions());
        return compilerResults.CompiledAssembly.GetType(string.Format("{0}.{1}", nameSpaceName, className));
    }

    private static CodeMemberField CreateBackingField(string name, Type type)
    {
        return new CodeMemberField
                   {
                       Attributes = MemberAttributes.Private,
                       Name = string.Format("_{0}", name),
                       Type = new CodeTypeReference(type)
                   };
    }
}
爱你是孤单的心事 2024-10-11 09:22:40

如果您知道数据在数组中的位置,那么您可以简单地执行以下操作:

  1. 创建一个包含您想要的所有属性的类
  2. myObject.name = array[0]; myObject.age = 数组[1];

If you know the position of the data in the array, then you could simply do this:

  1. Create a class with all the attributes you want
  2. myObject.name = array[0]; myObject.age = array[1];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文