欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#模板生成

程序员文章站 2024-02-18 16:24:16
...
简要说明

 创建代码有多种方式。最简单的,就按编辑器最初始的方法生成。稍微会点的就可以自己修改编辑器的模板。再深入一点的就可以自己定义一系列代码模板,保存到文本文件,再读出来,然后修改一些模板信息。用unity3d程序,我倒是习惯了在这程序中创建一个script而不是在vistual studio中去新建代码。这样的话,所有的代码类型,如Interface,struct,enum都需要在创建出一个”不正确“的类后修改,修改是个重复的过程,这个过程必须去掉。

 而遗憾的是unity至今还是对所有的代码一视同仁,连图标都是用c#这么“经典”的一个图标。前一段时候,用过一些方法,无非是编写一个代码模板文档,创建时,调用这些模板。最大的缺陷是太复杂,在不同的项目或电脑上都要靠一些不想要的模板文件。

 本文将使用Microsoft自己带的代码格式方案实现代码的生成(因为考虑到unity3d中暂不能很好的使用.net4.5,代码解析的模块还没有开发)。

成果展示

 1.如果你喜欢简单一点,直接点右键快速创建不同的类

C#模板生成

2.当然,也有基本的配制窗口

 C#模板生成

 3.如果你需要创建一个不继承于其他类的数据模型类,你可以这样配制

 C#模板生成

 4.以上这个配制后,点击create就可以生成代码模板到指定的文件夹了

 C#模板生成

5.以下是一个接口,创建效果。此外你已经熟悉代码规范了就可以在设置里面取消显示

 C#模板生成

技术要点

 1.将c#代码单元生成字符串

  代码也是一个个的文档,官方都有文档的格式,c#也不例外。这里只是按格式写,然后生成字符串,

需要说明的是c#并不能真的从string变成文档结构,至少官方貌似没有提供,但如果你可以使用net4.5以上的环境,

倒是可以研究下NRefactory

  using (Microsoft.CSharp.CSharpCodeProvider cprovider = new Microsoft.CSharp.CSharpCodeProvider())
            {
                StringBuilder fileContent = new StringBuilder();
                var option = new System.CodeDom.Compiler.CodeGeneratorOptions();
                option.BlankLinesBetweenMembers = false;
                using (StringWriter sw = new StringWriter(fileContent))
                {
                    cprovider.GenerateCodeFromNamespace(nameSpace, sw, option);
                }
                return fileContent.ToString();
            }

2.结合unity自己创建代码的方式

因为还没有找到,unity3d当前打开的文件夹路径,所以用了一个妥协的方案。就是先调用自带的方法创建一个脚本,

然后去修改里面的字符串(如果你找到了,不防提醒了一下)

        internal static void QuickCreateTemplate<T>() where T : ScriptTemplate, new()
        {
            EditorApplication.ExecuteMenuItem("Assets/Create/C# Script");
            EditorApplication.update = () =>
            {
                if (Selection.activeObject)
                {
                    var path = AssetDatabase.GetAssetPath(Selection.activeObject);
                    var temp = new T();
                    temp.headerInfo.scriptName = Path.GetFileNameWithoutExtension(path);
                    var dir = Path.GetDirectoryName(path);
                    var scr = temp.CreateScript();
                    temp.SaveToFile(dir, scr);
                    EditorApplication.update = null;
                }
            };
        }
 3.窗体缓存

因为,将窗体的信息保存到本地文件,但又想要缓存一点信息,所以用了EditorPrefs和PlayerPrefs,

前面用来保存跨工程的用户信息和窗体信息,后面用来保存当前程序的信息。即使这样,因为要缓存模板抽象类的信息,

还用到了类型记录的一些方案

        public static TempScriptWindow GetWindow()
        {
            var window = EditorWindow.GetWindow<TempScriptWindow>();
            if (EditorPrefs.HasKey(prefer_key))
            {
                var json = EditorPrefs.GetString(prefer_window);
                JsonUtility.FromJsonOverwrite(json, window);
                window.LoadOldTemplates();
                return window;
            }
            return window;
        }
 
  internal static ScriptTemplate LoadFromJson(ScriptTemplate old)
        {
            if (!string.IsNullOrEmpty(old.type) && old.GetType().FullName != old.type)
            {
                var type = Type.GetType(old.type);
                if(type != null)
                {
                    var temp = Activator.CreateInstance(type);
                    JsonUtility.FromJsonOverwrite(old.json, temp);
                    return temp as ScriptTemplate;
                }
                else
                {
                    return old;
                }
            }
            else
            {
                old.type = old.GetType().FullName;
                return old;
            }
        }
 4.unity3d自带列表ReorderableList

 以前没发现这个类,所以用了其他的插件来写列表。以上你看到的列表效果就是这样写的

        protected void InitDetailList()
        {
            detailList = new ReorderableList(headerInfo.detailInfo, typeof(string), true, false, true, true);
            detailList.onAddCallback += (x) => { headerInfo.detailInfo.Add(""); };
            detailList.drawHeaderCallback = (x) => { EditorGUI.LabelField(x, "详细信息"); };
            detailList.drawElementCallback += (x, y, z, w) => { headerInfo.detailInfo[y] = EditorGUI.TextField(x, headerInfo.detailInfo[y]); };
        }


源码分享

 为了方便拷贝使用,我直接在一个脚本中写了这些功能。虽然用了面对象的基本思路,但实际上在个文档中写,实在是难过,以后也尽量不要这样干。主要的是这个代码后面应该还会更新,如果喜欢,或者有建议可以到我github中去找:https://github.com/zouhunter/Editor_Extends/blob/master/Core/Editor/TempScriptWindow.cs

#region statement
/************************************************************************************* 
    * 作    者:       zouhunter
    * 时    间:       2018-02-02 
    * 详    细:       1.支持枚举、模型、结构和继承等类的模板。
                       2.支持快速创建通用型UI界面脚本
                       3.支持自定义模板类
                       4.自动生成作者、创建时间、描述等功能
                       5.支持工程同步(EditorPrefer)
   *************************************************************************************/
#endregion

using System;
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using UnityEditorInternal;
using System.CodeDom;
using System.IO;
using System.Text;
using NUnit.Framework.Constraints;
using NUnit.Framework;

namespace EditorTools
{
    #region Window
    /// <summary>
    /// 一个创建脚本模板的窗口
    /// </summary>
    public class TempScriptWindow : EditorWindow
    {
        [MenuItem("Window/TempScriptWindow")]
        static void Open()
        {
            var window = TempScriptHelper.GetWindow();
            window.wantsMouseMove = true;
        }


        [SerializeField]
        private List<ScriptTemplate> templates;
        ScriptTemplate currentTemplates { get { if (templates != null && templates.Count > currentIndex) return templates[currentIndex]; return null; } }
        private MonoScript script;
        [SerializeField]
        private bool isSetting;
        [SerializeField]
        private string authorName;
        [SerializeField]
        private string[] templateNames;
        [SerializeField]
        private int currentIndex;
        private Vector2 scrollPos;
        [SerializeField]
        private string[] templateType;
        private bool showRule;
        private string codeRule;
        private void OnEnable()
        {
            InitEnviroment();
        }

        private void OnDisable()
        {
            if (templates != null)
            {
                foreach (var item in templates)
                {

                    item.SaveToJson();
                }
            }
            EditorUtility.SetDirty(this);
            TempScriptHelper.SaveWindow(this);
        }
        private void OnGUI()
        {
            DrawHead();
            if (isSetting)
            {
                //绘制设置信息
                DrawSettings();
            }
            else
            {
                if (templates == null)
                {
                    Debug.Log("template == null");
                    templates = new List<ScriptTemplate>();
                }

                if (templates.Count == 0)
                {
                    Debug.Log("AddTemplates");
                    AddTemplates();
                }

                currentIndex = GUILayout.Toolbar(currentIndex, templateNames);
                using (var scroll = new EditorGUILayout.ScrollViewScope(scrollPos))
                {
                    scrollPos = scroll.scrollPosition;

                    if (currentTemplates != null)
                    {
                        if (currentTemplates.GetType().FullName != currentTemplates.type)
                        {
                            templates[currentIndex] = TempScriptHelper.LoadFromJson(currentTemplates);
                        }

                        currentTemplates.OnBodyGUI();

                        if (currentTemplates.GetType().FullName == typeof(ScriptTemplate).FullName)
                        {
                            if (templateType.Length > currentIndex)
                            {
                                var type = Type.GetType(templateType[currentIndex]);
                                if(type != null)
                                {
                                    templates[currentIndex] = Activator.CreateInstance(type) as ScriptTemplate;
                                    Debug.Log("create new:" + currentTemplates.GetType());
                                }
                                else
                                {
                                    Debug.LogFormat("{0} missing: clear templates", currentTemplates.GetType().FullName);
                                    templates.Clear();
                                }
                              
                            }
                            else
                            {
                                Debug.Log("unknow err: clear templates");
                                templates.Clear();
                            }
                        }
                    }
                    else
                    {
                        templates.Clear();
                        Debug.Log("templates.Count <= currentIndex");
                    }
                }
                if (currentTemplates != null)
                {
                    currentTemplates.OnFootGUI();
                }

            }

        }


        private void InitEnviroment()
        {
            if (script == null) script = MonoScript.FromScriptableObject(this);
            showRule = TempScriptHelper.GetRuleShowState();
            if (string.IsNullOrEmpty(codeRule)) codeRule = TempScriptHelper.GetCodeRule();
            if (string.IsNullOrEmpty(authorName)) authorName = TempScriptHelper.GetAuthor();
            if (string.IsNullOrEmpty(authorName))
            {
                isSetting = true;
            }
        }

        private void AddTemplates()
        {
            var assemble = this.GetType().Assembly;
            var allTypes = assemble.GetTypes();
            foreach (var item in allTypes)
            {
                if (item.IsSubclassOf(typeof(ScriptTemplate)))
                {
                    var template = Activator.CreateInstance(item);
                    templates.Add(template as ScriptTemplate);
                }
            }

            foreach (var item in templates)
            {
                item.OnEnable();
            }
            templateNames = templates.ConvertAll<string>(x => x.Name).ToArray();
            templateType = templates.ConvertAll<string>(x => x.GetType().FullName).ToArray();
        }

        public void LoadOldTemplates()
        {
            for (int i = 0; i < templates.Count; i++)
            {
                if (templates[i] == null)
                {
                    templates = null;
                    return;
                }

                var newitem = TempScriptHelper.LoadFromJson(templates[i]);

                if (newitem == null)
                {
                    templates = null;
                    return;
                }
                templates[i] = newitem;
            }
            templateNames = templates.ConvertAll<string>(x => x.Name).ToArray();
            templateType = templates.ConvertAll<string>(x => x.GetType().FullName).ToArray();
        }

        private void DrawHead()
        {
            using (var hor = new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.ObjectField(script, typeof(MonoScript), false);
                if (!isSetting && GUILayout.Button("setting", EditorStyles.miniButtonRight, GUILayout.Width(60)))
                {
                    isSetting = true;
                }
                else if (isSetting && GUILayout.Button("confer", EditorStyles.miniButtonRight, GUILayout.Width(60)) && !string.IsNullOrEmpty(authorName))
                {
                    isSetting = false;
                }
            }

            if (!isSetting && GUILayout.Button("Clear", EditorStyles.toolbarButton))
            {
                if (currentTemplates != null)
                    currentTemplates.headerInfo = new TempScriptHeader() ;
                templates.Clear();
            }
        }

        private void DrawSettings()
        {
            using (var hor = new EditorGUILayout.HorizontalScope())
            {
                EditorGUI.BeginChangeCheck();
                EditorGUILayout.SelectableLabel("作者:", EditorStyles.miniLabel, GUILayout.Width(60));
                authorName = EditorGUILayout.TextField(authorName);
                if (EditorGUI.EndChangeCheck())
                {
                    if (!string.IsNullOrEmpty(authorName))
                    {
                        TempScriptHelper.SaveAuthor(authorName);
                    }
                }
            }
            EditorGUI.BeginChangeCheck();
            showRule = EditorGUILayout.ToggleLeft("在生成的代码末尾显示规范:(熟悉后可关闭此功能)", showRule);
            if (EditorGUI.EndChangeCheck())
            {
                TempScriptHelper.SetRuleShowState(showRule);
            }

            if (showRule)
            {
                using (var scrop = new EditorGUILayout.ScrollViewScope(scrollPos))
                {
                    scrollPos = scrop.scrollPosition;
                    EditorGUILayout.TextArea(codeRule);
                }
            }
        }


    }
    #endregion

    #region Tools
    /// <summary>
    /// 任何脚本的头
    /// </summary>
    [System.Serializable]
    public class TempScriptHeader
    {
        public string author;
        public string time;
        public string description;
        public List<string> detailInfo = new List<string>();
        public string scriptName;
        public string nameSpace;

        public void Update()
        {
            author = TempScriptHelper.GetAuthor();
            time = System.DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
        }
    }

    /// <summary>
    /// 静态工具类
    /// </summary>
    public static class TempScriptHelper
    {
        private const string prefer_key = "temp_script_autor_name";
        private const string prefer_window = "temp_script_window";
        private const string code_rule_show = "temp_script_code_rule_show";

        public static void SaveAuthor(string author)
        {
            EditorPrefs.SetString(prefer_key, author);
        }

        public static string GetAuthor()
        {
            return EditorPrefs.GetString(prefer_key);
        }

        public static void SaveWindow(TempScriptWindow window)
        {
            var json = JsonUtility.ToJson(window);
            EditorPrefs.SetString(prefer_window, json);
        }
        public static TempScriptWindow GetWindow()
        {
            var window = EditorWindow.GetWindow<TempScriptWindow>();
            if (EditorPrefs.HasKey(prefer_key))
            {
                var json = EditorPrefs.GetString(prefer_window);
                JsonUtility.FromJsonOverwrite(json, window);
                window.LoadOldTemplates();
                return window;
            }
            return window;
        }
        internal static ScriptTemplate LoadFromJson(ScriptTemplate old)
        {
            if (!string.IsNullOrEmpty(old.type) && old.GetType().FullName != old.type)
            {
                var type = Type.GetType(old.type);
                if(type != null)
                {
                    var temp = Activator.CreateInstance(type);
                    JsonUtility.FromJsonOverwrite(old.json, temp);
                    return temp as ScriptTemplate;
                }
                else
                {
                    return old;
                }
            }
            else
            {
                old.type = old.GetType().FullName;
                return old;
            }
        }

        internal static void SetRuleShowState(bool enabled)
        {
            PlayerPrefs.SetInt(code_rule_show, enabled ? 1 : 0);
        }
        internal static bool GetRuleShowState()
        {
            if (PlayerPrefs.HasKey(code_rule_show))
            {
                return PlayerPrefs.GetInt(code_rule_show) == 1;
            }
            return true;
        }
        /*
         1.私有字段:_field,m_field
         2.公有字段:field
         2.属性:Property
         3.常量:CONST
         4.静态变量:Field,Property
             */
        internal static string GetCodeRule()
        {
            return @"#region 代码规范
/*************************************************************************************
        【变量命名】:
         1.私有字段:_field,m_field
         2.公有字段:field
         2.属性:Property
         3.常量:CONST
         4.静态变量:Field,Property
**************************************************************************************/
#endregion
";
        }

        internal static void QuickCreateTemplate<T>() where T : ScriptTemplate, new()
        {
            EditorApplication.ExecuteMenuItem("Assets/Create/C# Script");
            EditorApplication.update = () =>
            {
                if (Selection.activeObject)
                {
                    var path = AssetDatabase.GetAssetPath(Selection.activeObject);
                    var temp = new T();
                    temp.headerInfo.scriptName = Path.GetFileNameWithoutExtension(path);
                    var dir = Path.GetDirectoryName(path);
                    var scr = temp.CreateScript();
                    temp.SaveToFile(dir, scr);
                    EditorApplication.update = null;
                }
            };
        }
    }
    #endregion

    #region Templates
    /// <summary>
    /// 代码创建模板的模板
    /// </summary>
    [System.Serializable]
    public class ScriptTemplate
    {
        [System.Serializable]
        public class FieldItem
        {
            public string type;
            public string elementName;
            public string comment;
        }
        [System.Serializable]
        public class PropertyItem
        {
            public string type;
            public string elementName;
            public string comment;
            public bool get;
            public bool set;
            public PropertyItem()
            {
                get = set = true;
            }
        }
        [SerializeField]
        protected List<FieldItem> fields = new List<FieldItem>();
        [SerializeField]
        protected List<PropertyItem> propertys = new List<PropertyItem>();

        public string json;
        public string type;
        public TempScriptHeader headerInfo = new TempScriptHeader();
        public string path;
        public virtual string Name { get { return null; } }
        private ReorderableList detailList;

        public virtual void OnBodyGUI() { }
        public virtual void OnFootGUI()
        {
            if (detailList == null)
            {
                InitDetailList();
            }

            if (detailList.list != headerInfo.detailInfo)
            {
                detailList.list = headerInfo.detailInfo;
            }

            using (var horm = new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("Namespace", GUILayout.Width(70));
                headerInfo.nameSpace = EditorGUILayout.TextField(headerInfo.nameSpace, GUILayout.Width(60));
                EditorGUILayout.LabelField("Type", GUILayout.Width(40));
                headerInfo.scriptName = EditorGUILayout.TextField(headerInfo.scriptName, GUILayout.Width(60));
                EditorGUILayout.LabelField("简介", GUILayout.Width(40));
                headerInfo.description = EditorGUILayout.TextField(headerInfo.description);

                if (GUILayout.Button("Load", EditorStyles.miniButtonRight, GUILayout.Width(60)))
                {
                    OnLoadButtonClicked();
                }
            }
            using (var hor = new EditorGUILayout.HorizontalScope())
            {
                using (var vertical = new EditorGUILayout.VerticalScope())
                {
                    detailList.DoLayoutList();
                }
                using (var vertical = new EditorGUILayout.VerticalScope(GUILayout.Width(60)))
                {
                    if (GUILayout.Button("Create", EditorStyles.miniButtonRight, GUILayout.Height(60)))
                    {
                        OnCreateButtonClicked();
                    }
                }
            }
        }

        public void OnEnable()
        {
            type = this.GetType().FullName;
            Debug.Log(type);
        }

        public string CreateScript()
        {
            var ns = CreateNameSpace();
            if (ns == null) return null;
            var nsstr = ComplieNameSpaceToString(ns);
            if (string.IsNullOrEmpty(nsstr)) return null;

            var scriptStr = GetHeader() + nsstr + GetFooter();

            if (string.IsNullOrEmpty(scriptStr))
            {
                EditorUtility.DisplayDialog("生成失败", "请看日志!", "确认");
                return null;
            }

            return scriptStr;


        }
        public void SaveToJson()
        {
            json = null;
            json = JsonUtility.ToJson(this);
            if (string.IsNullOrEmpty(type))
            {
                type = this.GetType().FullName;
            }
        }
        protected void InitDetailList()
        {
            detailList = new ReorderableList(headerInfo.detailInfo, typeof(string), true, false, true, true);
            detailList.onAddCallback += (x) => { headerInfo.detailInfo.Add(""); };
            detailList.drawHeaderCallback = (x) => { EditorGUI.LabelField(x, "详细信息"); };
            detailList.drawElementCallback += (x, y, z, w) => { headerInfo.detailInfo[y] = EditorGUI.TextField(x, headerInfo.detailInfo[y]); };
        }

        protected void DrawFieldItem(Rect rect, FieldItem dataItem, bool haveType)
        {
            if (haveType)
            {
                var rect01 = new Rect(rect.x, rect.y, rect.width * 0.2f, EditorGUIUtility.singleLineHeight);
                var typeRect = new Rect(rect.x + 0.2f * rect.width, rect.y, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
                var rect02 = new Rect(rect.x + rect.width * 0.3f, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight);
                var commentRect = new Rect(rect.x + 0.6f * rect.width, rect.y, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
                var rect03 = new Rect(rect.x + rect.width * 0.7f, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight);

                dataItem.elementName = EditorGUI.TextField(rect01, dataItem.elementName);
                EditorGUI.LabelField(typeRect, "Type");
                dataItem.type = EditorGUI.TextField(rect02, dataItem.type);
                EditorGUI.LabelField(commentRect, "Comment");
                dataItem.comment = EditorGUI.TextField(rect03, dataItem.comment);
            }
            else
            {
                var left = new Rect(rect.x, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight);
                var right = new Rect(rect.x + rect.width * 0.4f, rect.y, rect.width * 0.6f, EditorGUIUtility.singleLineHeight);
                var center = new Rect(rect.x + rect.width * 0.3f, rect.y, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
                dataItem.elementName = EditorGUI.TextField(left, dataItem.elementName);
                EditorGUI.LabelField(center, "Comment");
                dataItem.comment = EditorGUI.TextField(right, dataItem.comment);
            }

        }
        protected void DrawPropertyItem(Rect rect, PropertyItem propertyItem)
        {
            var rect01 = new Rect(rect.x, rect.y, rect.width * 0.2f, EditorGUIUtility.singleLineHeight);
            var typeRect = new Rect(rect.x + 0.2f * rect.width, rect.y, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
            var rect02 = new Rect(rect.x + rect.width * 0.3f, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight);
            var commentRect = new Rect(rect.x + 0.6f * rect.width, rect.y, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
            var rect03 = new Rect(rect.x + rect.width * 0.7f, rect.y, rect.width * 0.3f, EditorGUIUtility.singleLineHeight);

            propertyItem.elementName = EditorGUI.TextField(rect01, propertyItem.elementName);
            EditorGUI.LabelField(typeRect, "Type");
            propertyItem.type = EditorGUI.TextField(rect02, propertyItem.type);
            EditorGUI.LabelField(commentRect, "Comment");
            propertyItem.comment = EditorGUI.TextField(rect03, propertyItem.comment);

            var getLabelRect = new Rect(rect.x, rect.y + EditorGUIUtility.singleLineHeight, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
            var getRect = new Rect(rect.x + 0.1f * rect.width, rect.y + EditorGUIUtility.singleLineHeight, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
            var setLabelRect = new Rect(rect.x + 0.2f * rect.width, rect.y + EditorGUIUtility.singleLineHeight, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);
            var setRect = new Rect(rect.x + 0.3f * rect.width, rect.y + EditorGUIUtility.singleLineHeight, rect.width * 0.1f, EditorGUIUtility.singleLineHeight);

            EditorGUI.LabelField(getLabelRect, "get");
            propertyItem.get = EditorGUI.Toggle(getRect, propertyItem.get);
            EditorGUI.LabelField(setLabelRect, "set");
            propertyItem.set = EditorGUI.Toggle(setRect, propertyItem.set);

        }

        protected virtual CodeNamespace CreateNameSpace()
        {
            return null;
        }
        protected string GetHeader()
        {
            headerInfo.Update();

            var str1 = "#region statement\r\n" +
            "/*************************************************************************************   \r\n" +
            "    * 作    者:       {0}\r\n" +
            "    * 时    间:       {1}\r\n" +
            "    * 说    明:       ";
            var str2 = "\r\n                       ";
            var str3 = "\r\n* ************************************************************************************/" +
            "\r\n#endregion\r\n";

            var headerStr = string.Format(str1, headerInfo.author, headerInfo.time);
            for (int i = 0; i < headerInfo.detailInfo.Count; i++)
            {
                if (i == 0)
                {
                    headerStr += string.Format("{0}.{1}", i + 1, headerInfo.detailInfo[i]);
                }
                else
                {
                    headerStr += string.Format("{0}{1}.{2}", str2, i + 1, headerInfo.detailInfo[i]);
                }
            }
            headerStr += str3;
            return headerStr;
        }
        protected string ComplieNameSpaceToString(CodeNamespace nameSpace)
        {
            using (Microsoft.CSharp.CSharpCodeProvider cprovider = new Microsoft.CSharp.CSharpCodeProvider())
            {
                StringBuilder fileContent = new StringBuilder();
                var option = new System.CodeDom.Compiler.CodeGeneratorOptions();
                option.BlankLinesBetweenMembers = false;
                using (StringWriter sw = new StringWriter(fileContent))
                {
                    cprovider.GenerateCodeFromNamespace(nameSpace, sw, option);
                }
                return fileContent.ToString();
            }
        }
        protected string GetFooter()
        {
            if (TempScriptHelper.GetRuleShowState())
            {
                var rule = TempScriptHelper.GetCodeRule();
                return rule;
            }
            return null;
        }
        /// <summary>
        /// 点击创建
        /// </summary>
        private void OnCreateButtonClicked()
        {
            if (string.IsNullOrEmpty(headerInfo.scriptName))
            {
                EditorUtility.DisplayDialog("脚本名为空", "请填写代码名称!", "确认");
                return;
            }


            if (string.IsNullOrEmpty(path))
            {
                if (ProjectWindowUtil.IsFolder(Selection.activeInstanceID))
                {
                    path = AssetDatabase.GetAssetPath(Selection.activeInstanceID);
                }
                else if (Selection.activeObject != null)
                {
                    var assetPath = AssetDatabase.GetAssetPath(Selection.activeObject);
                    if (!string.IsNullOrEmpty(assetPath))
                    {
                        path = assetPath.Replace(System.IO.Path.GetFileName(assetPath), "");
                    }
                }
            }
            var scriptStr = CreateScript();
            if (!string.IsNullOrEmpty(scriptStr))
            {
                SaveToFile(path, scriptStr);
            }

        }
        /// <summary>
        /// 保存到文件
        /// </summary>
        /// <param name="path"></param>
        /// <param name="scriptStr"></param>
        public void SaveToFile(string path, string scriptStr)
        {
            if (!string.IsNullOrEmpty(path))
            {
                var scriptPath = string.Format("{0}/{1}.cs", path, headerInfo.scriptName);
                System.IO.File.WriteAllText(scriptPath, scriptStr, System.Text.Encoding.UTF8);
                AssetDatabase.Refresh();
            }
            else
            {
                EditorUtility.DisplayDialog("路径不明", "请选中文件夹后重试", "确认");
            }

        }

        /// <summary>
        /// 点击加载代码
        /// </summary>
        private void OnLoadButtonClicked()
        {
            if (!(Selection.activeObject is TextAsset))
            {
                EditorUtility.DisplayDialog("未选中", "请选中需要解析的代码后继续", "确认");
                return;
            }

            var path = AssetDatabase.GetAssetPath(Selection.activeObject);
            if (!path.EndsWith(".cs"))
            {
                EditorUtility.DisplayDialog("未选中", "请选中需要解析的代码后继续", "确认");
                return;
            }

            using (var provider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("CSharp"))
            {
                EditorUtility.DisplayDialog("未开发", ".net 3.5暂无该实现", "确认");

                var fileContent = System.IO.File.ReadAllText(path, Encoding.UTF8);
                using (StringReader sr = new StringReader(fileContent))
                {
                    var nameSpaceUnit = provider.Parse(sr);
                    Debug.Log(nameSpaceUnit);
                }
            }
        }
    }
    #endregion

    #region Enum
    /// <summary>
    /// 1.枚举类型脚本
    /// </summary>
    [Serializable]
    public class EnumScriptTemplate : ScriptTemplate
    {
        [MenuItem("Assets/Create/C# TempScripts/Enum", priority = 5)]
        static void CreateEnum()
        {
            TempScriptHelper.QuickCreateTemplate<EnumScriptTemplate>();
        }

        public override string Name
        {
            get
            {
                return "Enum";
            }
        }

        private ReorderableList reorderableList;

        public EnumScriptTemplate()
        {
            reorderableList = new ReorderableList(fields, typeof(string));
            reorderableList.onAddCallback += (x) => { fields.Add(new FieldItem()); };
            reorderableList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "枚举列表"); };
            reorderableList.drawElementCallback += (x, y, z, w) =>
            {
                DrawFieldItem(x, fields[y], false);
            };
        }

        protected override CodeNamespace CreateNameSpace()
        {
            List<CodeMemberField> fields = new List<CodeMemberField>();
            foreach (var item in base.fields)
            {
                CodeMemberField prop = new CodeMemberField();
                prop.Name = item.elementName;
                prop.Comments.Add(new CodeCommentStatement(item.comment));
                fields.Add(prop);
            }

            CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration(headerInfo.scriptName);
            wrapProxyClass.TypeAttributes = System.Reflection.TypeAttributes.Public;
            wrapProxyClass.IsEnum = true;

            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement(headerInfo.description, true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            foreach (var field in fields)
            {
                wrapProxyClass.Members.Add(field);
            }

            CodeNamespace nameSpace = new CodeNamespace(headerInfo.nameSpace);
            nameSpace.Types.Add(wrapProxyClass);
            return nameSpace;
        }
        public override void OnBodyGUI()
        {
            reorderableList.DoLayoutList();
        }
    }
    #endregion

    #region DataModel
    /// <summary>
    /// 2.数据模拟类
    /// </summary>
    [Serializable]
    public class DataModelTemplate : ScriptTemplate
    {
        [MenuItem("Assets/Create/C# TempScripts/Model", priority = 5)]
        static void CreateModel()
        {
            TempScriptHelper.QuickCreateTemplate<DataModelTemplate>();
        }
        public override string Name
        {
            get
            {
                return "Model";
            }
        }

        [SerializeField]
        private List<string> imports = new List<string>() {
            "System",
            "UnityEngine",
            "UnityEngine.UI",
            "System.Collections",
            "System.Collections.Generic",
        };
        private ReorderableList nameSpaceList;
        private ReorderableList reorderableList;

        public DataModelTemplate()
        {
            reorderableList = new ReorderableList(fields, typeof(string));
            reorderableList.onAddCallback += (x) => { fields.Add(new FieldItem()); };
            reorderableList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "模型名"); };
            reorderableList.drawElementCallback += (x, y, z, w) =>
            {
                DrawFieldItem(x, fields[y], true);
            };

            nameSpaceList = new ReorderableList(imports, typeof(string));
            nameSpaceList.onAddCallback += (x) => { imports.Add(""); };
            nameSpaceList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "命名空间"); };
            nameSpaceList.drawElementCallback += (x, y, z, w) =>
            {
                imports[y] = DrawNameSpace(x, imports[y]);
            };
        }

        protected override CodeNamespace CreateNameSpace()
        {
            List<CodeMemberField> fields = new List<CodeMemberField>();
            foreach (var item in base.fields)
            {
                CodeMemberField prop = new CodeMemberField();
                prop.Type = new CodeTypeReference(item.type, CodeTypeReferenceOptions.GenericTypeParameter);
                prop.Attributes = MemberAttributes.Public;
                prop.Name = item.elementName;
                prop.Comments.Add(new CodeCommentStatement(item.comment));
                fields.Add(prop);
            }

            CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration(headerInfo.scriptName);
            wrapProxyClass.TypeAttributes = System.Reflection.TypeAttributes.Public;
            wrapProxyClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(System.SerializableAttribute).FullName));
            wrapProxyClass.IsClass = true;
            var destription = string.IsNullOrEmpty(headerInfo.description) ? "数据模型" : headerInfo.description;
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement(destription, true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            foreach (var field in fields)
            {
                wrapProxyClass.Members.Add(field);
            }
            CodeNamespace nameSpace = new CodeNamespace(headerInfo.nameSpace);
            nameSpace.Types.Add(wrapProxyClass);
            nameSpace.Imports.AddRange(imports.ConvertAll<CodeNamespaceImport>(x => new CodeNamespaceImport(x)).ToArray());
            return nameSpace;
        }


        private string DrawNameSpace(Rect rect, string dataItem)
        {
            var rect1 = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
            return EditorGUI.TextField(rect1, dataItem);
        }

        public override void OnBodyGUI()
        {
            nameSpaceList.DoLayoutList();
            reorderableList.DoLayoutList();
        }
    }
    #endregion

    #region Static
    /// <summary>
    /// 3.静态类
    /// </summary>
    [Serializable]
    public class StaticClassTemplate : ScriptTemplate
    {
        [MenuItem("Assets/Create/C# TempScripts/Static", priority = 5)]
        static void CreateModel()
        {
            TempScriptHelper.QuickCreateTemplate<StaticClassTemplate>();
        }
        public override string Name
        {
            get
            {
                return "Static";
            }
        }

        [SerializeField]
        private List<string> imports = new List<string>() {
            "System",
            "UnityEngine"
        };
        private ReorderableList nameSpaceList;
        private ReorderableList propertyList;
        private ReorderableList fieldList;

        public StaticClassTemplate()
        {
            fieldList = new ReorderableList(fields, typeof(string));
            fieldList.onAddCallback += (x) => { fields.Add(new FieldItem()); };
            fieldList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "字段"); };
            fieldList.drawElementCallback += (x, y, z, w) =>
            {
                DrawFieldItem(x, fields[y], true);
            };

            propertyList = new ReorderableList(propertys, typeof(string));
            propertyList.onAddCallback += (x) => { propertys.Add(new PropertyItem()); };
            propertyList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "属性"); };
            propertyList.elementHeightCallback = (x) => { return 2 * EditorGUIUtility.singleLineHeight; };
            propertyList.drawElementCallback += (x, y, z, w) =>
            {
                DrawPropertyItem(x, propertys[y]);
            };

            nameSpaceList = new ReorderableList(imports, typeof(string));
            nameSpaceList.onAddCallback += (x) => { imports.Add(""); };
            nameSpaceList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "命名空间"); };
            nameSpaceList.drawElementCallback += (x, y, z, w) =>
            {
                imports[y] = DrawNameSpace(x, imports[y]);
            };
        }


        protected override CodeNamespace CreateNameSpace()
        {
            List<CodeMemberField> codeFields = new List<CodeMemberField>();
            foreach (var item in fields)
            {
                CodeMemberField field = new CodeMemberField();
                field.Type = new CodeTypeReference(item.type, CodeTypeReferenceOptions.GenericTypeParameter);
                field.Attributes = MemberAttributes.Public | MemberAttributes.Static;
                field.Name = item.elementName;
                //field.InitExpression = invokeExpression;
                field.Comments.Add(new CodeCommentStatement(item.comment));
                codeFields.Add(field);
            }


            List<CodeMemberProperty> propertysMemper = new List<CodeMemberProperty>();
            foreach (var item in propertys)
            {
                CodeMemberProperty prop = new CodeMemberProperty();
                prop.Type = new CodeTypeReference(item.type, CodeTypeReferenceOptions.GenericTypeParameter);
                prop.Attributes = MemberAttributes.Public|MemberAttributes.Static;
                prop.Name = item.elementName;
                prop.HasGet = item.get;
                prop.HasSet = item.set;
                //CodeExpression invokeExpression = new CodePropertyReferenceExpression();
                prop.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
                prop.Comments.Add(new CodeCommentStatement(item.comment));
                propertysMemper.Add(prop);
            }

            CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration(headerInfo.scriptName);
            wrapProxyClass.TypeAttributes = System.Reflection.TypeAttributes.Public;//没有静态?
            wrapProxyClass.Attributes = MemberAttributes.Static;
            wrapProxyClass.IsClass = true;
            var destription = string.IsNullOrEmpty(headerInfo.description) ? "静态类" : headerInfo.description;
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement(destription, true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            foreach (var prop in propertysMemper)
            {
                wrapProxyClass.Members.Add(prop);
            }
            foreach (var field in codeFields)
            {
                wrapProxyClass.Members.Add(field);
            }
            CodeNamespace nameSpace = new CodeNamespace(headerInfo.nameSpace);
            nameSpace.Types.Add(wrapProxyClass);
            nameSpace.Imports.AddRange(imports.ConvertAll<CodeNamespaceImport>(x => new CodeNamespaceImport(x)).ToArray());
            return nameSpace;
        }

        private string DrawNameSpace(Rect rect, string dataItem)
        {
            var rect1 = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
            return EditorGUI.TextField(rect1, dataItem);
        }

        public override void OnBodyGUI()
        {
            nameSpaceList.DoLayoutList();
            fieldList.DoLayoutList();
            propertyList.DoLayoutList();
        }
    }

    #endregion

    #region Struct
    /// <summary>
    /// 5.结构体模板
    /// </summary>
    [Serializable]
    public class StructTempate : ScriptTemplate
    {
        [MenuItem("Assets/Create/C# TempScripts/Struct", priority = 5)]
        static void CreateStruct()
        {
            TempScriptHelper.QuickCreateTemplate<StructTempate>();
        }

        public override string Name
        {
            get
            {
                return "Struct";
            }
        }

        [SerializeField]
        private List<string> imports = new List<string>() {
            "System",
            "UnityEngine",
            "UnityEngine.UI",
            "System.Collections",
            "System.Collections.Generic",
        };
        private ReorderableList nameSpaceList;
        private ReorderableList reorderableList;

        public StructTempate()
        {
            reorderableList = new ReorderableList(fields, typeof(string));
            reorderableList.onAddCallback += (x) => { fields.Add(new FieldItem()); };
            reorderableList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "模型名"); };
            reorderableList.drawElementCallback += (x, y, z, w) =>
            {
                DrawFieldItem(x, fields[y], true);
            };

            nameSpaceList = new ReorderableList(imports, typeof(string));
            nameSpaceList.onAddCallback += (x) => { imports.Add(""); };
            nameSpaceList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "命名空间"); };
            nameSpaceList.drawElementCallback += (x, y, z, w) =>
            {
                imports[y] = DrawNameSpace(x, imports[y]);
            };
        }

        protected override CodeNamespace CreateNameSpace()
        {
            List<CodeMemberField> fields = new List<CodeMemberField>();
            foreach (var item in base.fields)
            {
                CodeMemberField prop = new CodeMemberField();
                prop.Type = new CodeTypeReference(item.type, CodeTypeReferenceOptions.GenericTypeParameter);
                prop.Attributes = MemberAttributes.Public;
                prop.Name = item.elementName;
                prop.Comments.Add(new CodeCommentStatement(item.comment));
                fields.Add(prop);
            }

            CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration(headerInfo.scriptName);
            wrapProxyClass.TypeAttributes = System.Reflection.TypeAttributes.Public;
            wrapProxyClass.IsStruct = true;
            var destription = string.IsNullOrEmpty(headerInfo.description) ? "结构体" : headerInfo.description;
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement(destription, true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            foreach (var field in fields)
            {
                wrapProxyClass.Members.Add(field);
            }
            CodeNamespace nameSpace = new CodeNamespace(headerInfo.nameSpace);
            nameSpace.Types.Add(wrapProxyClass);
            nameSpace.Imports.AddRange(imports.ConvertAll<CodeNamespaceImport>(x => new CodeNamespaceImport(x)).ToArray());
            return nameSpace;
        }

        private string DrawNameSpace(Rect rect, string dataItem)
        {
            var rect1 = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
            return EditorGUI.TextField(rect1, dataItem);
        }

        public override void OnBodyGUI()
        {
            nameSpaceList.DoLayoutList();
            reorderableList.DoLayoutList();
        }
    }
    #endregion

    #region Interface
    /// <summary>
    /// 6.接口创建模板
    /// </summary>
    [Serializable]
    public class InterfaceTempate : ScriptTemplate
    {
        [MenuItem("Assets/Create/C# TempScripts/Interface", priority = 5)]
        static void CreateEnum()
        {
            TempScriptHelper.QuickCreateTemplate<InterfaceTempate>();
        }

        public override string Name
        {
            get
            {
                return "Interface";
            }
        }

        [SerializeField]
        private List<string> imports = new List<string>() {
            "System",
            "UnityEngine"
        };
        private ReorderableList nameSpaceList;
        private ReorderableList reorderableList;

        public InterfaceTempate()
        {
            reorderableList = new ReorderableList(propertys, typeof(string));
            reorderableList.onAddCallback += (x) => { propertys.Add(new PropertyItem()); };
            reorderableList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "属性"); };
            reorderableList.elementHeightCallback = (x) => { return 2 * EditorGUIUtility.singleLineHeight; };
            reorderableList.drawElementCallback += (x, y, z, w) =>
            {
                DrawPropertyItem(x, propertys[y]);
            };

            nameSpaceList = new ReorderableList(imports, typeof(string));
            nameSpaceList.onAddCallback += (x) => { imports.Add(""); };
            nameSpaceList.drawHeaderCallback += (x) => { EditorGUI.LabelField(x, "命名空间"); };
            nameSpaceList.drawElementCallback += (x, y, z, w) =>
            {
                imports[y] = DrawNameSpace(x, imports[y]);
            };
        }


        protected override CodeNamespace CreateNameSpace()
        {
            List<CodeMemberProperty> propertysMemper = new List<CodeMemberProperty>();
            foreach (var item in propertys)
            {
                CodeMemberProperty prop = new CodeMemberProperty();
                prop.Type = new CodeTypeReference(item.type, CodeTypeReferenceOptions.GenericTypeParameter);
                prop.Attributes = MemberAttributes.Public;
                prop.Name = item.elementName;
                prop.HasGet = item.get;
                prop.HasSet = item.set;
                prop.Comments.Add(new CodeCommentStatement(item.comment));
                propertysMemper.Add(prop);
            }

            CodeTypeDeclaration wrapProxyClass = new CodeTypeDeclaration(headerInfo.scriptName);
            wrapProxyClass.TypeAttributes = System.Reflection.TypeAttributes.Public;
            wrapProxyClass.IsInterface = true;
            var destription = string.IsNullOrEmpty(headerInfo.description) ? "接口" : headerInfo.description;
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement(destription, true));
            wrapProxyClass.Comments.Add(new CodeCommentStatement("<summary>", true));
            foreach (var prop in propertysMemper)
            {
                wrapProxyClass.Members.Add(prop);
            }
            CodeNamespace nameSpace = new CodeNamespace(headerInfo.nameSpace);
            nameSpace.Types.Add(wrapProxyClass);
            nameSpace.Imports.AddRange(imports.ConvertAll<CodeNamespaceImport>(x => new CodeNamespaceImport(x)).ToArray());
            return nameSpace;
        }

        private string DrawNameSpace(Rect rect, string dataItem)
        {
            var rect1 = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
            return EditorGUI.TextField(rect1, dataItem);
        }

        public override void OnBodyGUI()
        {
            nameSpaceList.DoLayoutList();
            reorderableList.DoLayoutList();
        }
    }
    #endregion


    ///下面可以自定义你的代码生成模板
    ///...
    /// <summary>
    /// UI模板
    /// </summary>
    //[Serializable]
    //public class UIPanelTempate : ScriptTemplate
    //{
    //    public override string Name
    //    {
    //        get
    //        {
    //            return "UIPanel";
    //        }
    //    }

    //    protected override CodeNamespace CreateNameSpace()
    //    {
    //        return null;
    //    }

    //    public override void OnBodyGUI()
    //    {

    //    }
    //}

}