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

时间:2015-01-11 21:22:22

标签: c# unity3d mono code-generation codedom

假设我想创建一个带有代码文件,其中包含字段,其中包含一些非原始的非别名类型即可。让它成为众所周知的事物: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);

如果控件有一些类似通用或嵌套类型的“怪异”类型,它将生成无效代码。

1 个答案:

答案 0 :(得分:0)

如果你看一下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)生成代码有效。