开发者

Custom object in .NET

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 u开发者_JAVA技巧se generics, how to do that?


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.


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


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];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜