代码生成中的属性/字段初始化器 [英] Property / field initializers in code generation
问题描述
我正在使用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 using
s 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 using
s, 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屋!