代码生成中的属性/字段初始化器 [英] Property / field initializers in code generation

查看:101
本文介绍了代码生成中的属性/字段初始化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用CodeDom和纯代码字符串在Visual Studio扩展中生成代码.我的扩展程序使用反射读取当前声明的类的字段和属性,并生成构造函数,初始化程序,实现某些接口等.

I'm generating code in a visual studio extension using CodeDom and plain code strings. My extension reads a current classes declared fields and properties using reflection and generates contructors, initializers, implements certain interfaces, etc.

生成器类很简单:

public class CodeGenerator < T >  
{  
    public string GetCode ()  
    {  
        string code = "";  
        T type = typeof(T);  
        List < PropertyInfo > properties = t.GetProperties();  
        foreach (PropertyInfo property in properties)  
            code += "this." + property.Name + " = default(" + property.PropertyType.Name + ")";  
    }  
}

我通过两种方式停留在字段和属性初始化程序上.

I'm stuck at field and property initializers in two ways.

首先,尽管default(AnyNonGenericValueOrReferenceType)在大多数情况下都可以工作,但我对在生成的代码中使用它感到不舒服.

Firstly, although default(AnyNonGenericValueOrReferenceType) seems to work in most cases, I'm uncomfortable with using it in generated code.

第二,它不适用于泛型类型,因为我找不到找到泛型类型基础类型的方法.因此,如果属性为List < int >,则property.PropertyType.Name返回List`1.这里有两个问题.首先,我需要在不使用字符串操作的情况下为泛型类型获取适当的名称.其次,我需要访问基础类型.完整的属性类型名称返回如下内容:

Secondly, it does not work for generic types since I can't find a way to get the underlying type of the generic type. So if a property is List < int >, property.PropertyType.Name returns List`1. There are two problems here. First, I need to get the proper name for the generic type without using string manipulation. Second, I need to access the underlying type. The full property type name returns something like:


System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

推荐答案

如果确定要使用字符串,则必须编写自己的方法来格式化那些类型名称.像这样:

If you are sure you want to use strings, you will have to write your own method to format those type names. Something like:

static string FormatType(Type t)
{
    string result = t.Name;

    if (t.IsGenericType)
    {
        result = string.Format("{0}<{1}>",
            result.Split('`')[0],
            string.Join(",", t.GetGenericArguments().Select(FormatType)));
    }

    return result;
}

此代码假定您的文件中包含所有必需的using.

This code assumes you have all necessary usings in your file.

但是我认为实际使用CodeDOM的对象模型要好得多.这样,您不必担心using,格式类型或错别字:

But I think it's much better to actually use CodeDOM's object model. This way, you don't have to worry about usings, formatting types or typos:

var statement =
    new CodeAssignStatement(
        new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), property.Name),
        new CodeDefaultValueExpression(new CodeTypeReference(property.PropertyType)));

如果您真的不想使用default(T),则可以找出该类型是引用类型还是值类型.如果是引用类型,请使用null.如果是值类型,则必须存在默认构造函数,因此可以调用它.

And if you really don't want to use default(T), you can find out whether the type is a reference or value type. If it's a reference type, use null. If it's value type, the default constructor has to exist, and so you can call that.

这篇关于代码生成中的属性/字段初始化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆