如何使用短类型名称而不是完整类型名称生成代码?

How to generate code with short type names instead of full type names?

假设我想创建一个代码文件,其中包含一个字段class =37=] 其中有一些非原始非别名 类型 。让它成为众所周知的东西:StreamWriter类型。

我添加 System.IO 导入以允许短类型引用。我以这种方式创建类型引用:

var type = new CodeTypeReference(typeof(StreamWriter));

但仍然会生成冗余类型前缀:

// ------------------------------------------------------------------------------
//  <autogenerated>
//      This code was generated by a tool.
//      Mono Runtime Version: 2.0.50727.1433
// 
//      Changes to this file may cause incorrect behavior and will be lost if 
//      the code is regenerated.
//  </autogenerated>
// ------------------------------------------------------------------------------

namespace Bar {
    using System.IO;


    public class Foo {

        private System.IO.StreamWriter baz;

    }
}

我知道我可以使用 string 解决问题:

var type = new CodeTypeReference("StreamWriter");
// or even
var type = new CodeTypeReference(typeof(StreamWriter).Name);

但应该有一些不错的 CodeDom 构建方式,不是吗?


P.S.: 第二种解决方法可能看起来足够类型安全,但我不知道具体类型,只知道它是从已知基类型派生的。所以,实际上它看起来像这样:

var type = new CodeTypeReference(controlData.Control.GetType().Name);

如果控件有一些“奇怪的”类型,如泛型或嵌套类型,它将生成有效代码。

如果你看看如何 CodeTypeReference construction from Type is implemented,你会发现你可以实施类似这样的解决方法:

    public static CodeTypeReference CreateShortCodeTypeReference(Type type, CodeNamespaceImportCollection imports)
    {
        var result = new CodeTypeReference(type);

        Shortify(result, type, imports);

        return result;
    }

    private static void Shortify(CodeTypeReference typeReference, Type type, CodeNamespaceImportCollection imports)
    {
        if (typeReference.ArrayRank > 0)
        {
            Shortify(typeReference.ArrayElementType, type, imports);
            return;
        }

        if (type.Namespace != null && imports.Cast<CodeNamespaceImport>()
            .Any(cni => cni.Namespace == type.Namespace))
        {
            var prefix = type.Namespace + '.';

            if (prefix != null)
            {
                var pos = typeReference.BaseType.IndexOf(prefix);
                if (pos == 0)
                {
                    typeReference.BaseType = typeReference.BaseType.Substring(prefix.Length);
                }
            }
        }
    }

用法:

var type = CreateShortCodeTypeReference(foo.GetType(), codeNamespace.Imports);

结果:

假设 using UnityEngine.UI; 存在:

  • UnityEngine.UI.Button → 按钮
  • UnityEngine.UI.Button[] → 按钮[]
  • UnityEngine.UI.Button[][][] → 按钮[][][]

限制:

  • 不会影响泛型类型参数,例如 List<System.IO.Path>
  • 仅对使用支持导入的 CLR 语言(如 C# 和 VB)生成代码有效。