zoukankan      html  css  js  c++  java
  • 通过反射实现Microsoft Visual Studio International Pack 1.0 SR1里面的两个类

       这两天打算实现拼音和简繁转换的方法, 发现Microsoft Visual Studio International Pack 1.0 SR1 提供了 .    下载地址

    但是基于某些原因,

    一来下载回来的是安装包 而某些msi文件安装必须安装VS2005或2008,比较麻烦.

    二来不想在每个工程里面都引用里面的DLL.

    所以打算把需要的Dll放入资源文件里面,然后调用里面的dll来实现.

    之前只知道反射这个概念,从没怎么研究过,原本以为有很多现成的代码可供研究,但终究只有一些大概的原理.

    最终去啃MSDN帮助,总算已经完成,记录下.

    首先在工程里面创建一个资源文件QuoteDll.resx.  然后建立ChinaChar和ChinaConverter类

     

    (注意:QuoteDll.resx应和两个类在同一个命名空间下) 

    下面就看代码吧!

    /**********************************创建记录**********************************
      类  描述: 此类使用内嵌ChineseConverter.dll和ChnCharInfo.dll的资源
      类    名: ChinaChar
      创建  者:yj.zhou
      创建日期:2017/12/12 星期一 15:05:50
      类  说明: 
                ChineseConverter.dll和ChnCharInfo.dll获取方法
                下载微软Microsoft Visual Studio International Pack 1.0 SR1语言包:
                解压“vsintlpack1.zip”,获得七个语言包。双击其中的“CHSPinYinConv.msi”
                完成安装后就可以在Visual Studio中引用ChnCharInfo.dll了。
                或从其它项目中直接引用ChineseConverter.dll和ChnCharInfo.dll 
                疑惑:           
                很多字有一个第5声(什么鬼?),所以
                ChineseChar(ChnCharInfo.dll)(ChnCharInfo.dll)类中PinyinCount并不准确.
                IsPolyphone判断他的是否多音字也未必正确.
    *******************************************************************************/
    using System;
    using System.Collections.ObjectModel;
    using System.Reflection;
    using static OperateClass.PropertyHelper;
     
    namespace OperateClass.Conver
    {
        /// <summary>
        /// 汉字相关类(主要是反射实现ChineseChar(ChnCharInfo.dll)的类)
        /// </summary>
        public class ChinaChar
        {
            #region 属性
     
            #region 私有属性/字段  
     
            private Type ChineseCharType;
     
            private object innerChnChar;
     
            #endregion
     
            #region 公共属性
            /// <summary>
            /// 获取这个汉字字符。 
            /// </summary>
            public char ChineseCharacter { get; }
     
            /// <summary>
            /// 获取这个字符是否是多音字。 
            /// </summary>
            public bool IsPolyphone { get; }
     
            /// <summary>
            /// 获取这个字符的拼音个数。
            /// </summary>
            public short PinyinCount { get; }
     
            /// <summary>
            /// 获取这个字符的拼音。
            /// </summary>
            public ReadOnlyCollection<string> Pinyins { get; }
     
            /// <summary>
            /// 获取这个字符的笔画数。 
            /// </summary>
            public short StrokeNumber { get; }
     
            #endregion
     
            #endregion
     
            #region 方法
     
            #region 私有方法
            /// <summary>
            /// 调用ChineseChar的构造方法(ChineseChar只有一个带char参数的构造方法)
            /// </summary>        
            /// <param name="chnChar">使用这个chnChar参数构造ChineseChar类型</param>
            /// <returns></returns>
            private object getChineseCharConstruct(char chnChar)
            {
                return Activator.CreateInstance(ChineseCharType, new object[] { chnChar });
            }
     
            private object getPublicPropertyValue(string propName)
            {
                return ChineseCharType.InvokeMember(
                    propName,
                    BindingFlags.DeclaredOnly |
                    BindingFlags.Public |
                    BindingFlags.Instance |
                    BindingFlags.GetProperty,
                    null, innerChnChar, null);
            }
     
            private object getPublicMethodResult(string methodName, Object[] args)
            {
                return ChineseCharType.InvokeMember(methodName,
                      BindingFlags.DeclaredOnly |
                      BindingFlags.Public |
                      BindingFlags.NonPublic |
                      BindingFlags.Instance |
                      BindingFlags.GetProperty, null, innerChnChar, null);
            } 
            #endregion
     
            #region 公共方法
     
            #region 构造方法
     
            /// <summary>
            /// 构造函数
            /// </summary>
            public ChinaChar(char chnChar)
            {
                ChineseCharType = getChineseCharType();
                if (ChineseCharType == null)
                {
                    throw new ArgumentNullException("不能获取资源文件定义的ChineseChar类");
                }
     
                innerChnChar = getChineseCharConstruct(chnChar);
     
                ChineseCharacter = (char)getPublicPropertyValue("ChineseCharacter");
                IsPolyphone = (bool)getPublicPropertyValue("IsPolyphone");
                PinyinCount = (short)getPublicPropertyValue("PinyinCount");
                // Pinyins = (ReadOnlyCollection<string>)getPublicPropertyValue("Pinyins");
     
                //这个方法必须保证类属性和 ChineseChar类的属性名是一样的,可以减少硬编码.
                Pinyins = (ReadOnlyCollection<string>)getPublicPropertyValue(
                    GetPropertyName(() => Pinyins));
            } 
            #endregion
     
            #region 实例方法
     
            /// <summary>
            /// 将给出的字符和实例字符的笔画数进行比较。
            /// </summary>
            /// <param name="chnChar">显示给出的字符</param>
            /// <returns>
            /// 说明比较操作的结果。 
            /// 如果给出字符和实例字符的笔画数相同,返回值等于 0。 
            /// 如果实例字符比给出字符的笔画多,返回值为大于 0。 
            /// 如果实例字符比给出字符的笔画少,返回值为小于 0。
            /// </returns>
            public int CompareStrokeNumber(char chnChar)
            {
                return (int)getPublicMethodResult("CompareStrokeNumber", new object[1] { chnChar });
            }
     
            /// <summary>
            /// 识别字符是否有指定的读音。(指定的拼音字符串是否在实例字符的拼音集合中)
            /// </summary>
            /// <param name="pinyin">指定的需要被识别的拼音。</param>
            /// <returns>
            /// 如果指定的拼音字符串在实例字符的拼音集合中则返回ture,否则返回false。
            /// </returns>
            public bool HasSound(string pinyin)
            {
                return this.Pinyins.Contains(pinyin);
            }
     
            /// <summary>
            /// 识别给出的字符是否是实例字符的同音字。
            /// </summary>
            /// <param name="chnChar">指出需要识别的字符。</param>
            /// <returns>如果给出的实例字符是同音字则返回ture,否则返回false。</returns>
            public bool IsHomophone(char chnChar)
            {
                return (bool)getPublicMethodResult("IsHomophone", new object[1] { chnChar });
            }
     
            #endregion
     
            #region 静态方法
            #region 私有静态方法
            private static Type getChineseCharType()
            {
                Type result = null;
                // Assembly ab = Assembly.Load("ChnCharInfo");
                Assembly ab = Assembly.Load(QuoteDll.ChnCharInfo);
                foreach (Type item in ab.GetTypes())
                {
                    if (item.IsClass && item.Name == "ChineseChar")
                    {
                        result = item;
                        break;
                    }
                }
                return result;
            }
     
            private static MethodInfo getChineseCharMethod(string methodName, Type[] parameters)
            {            
                return getChineseCharType().GetMethod(methodName, parameters);
            }
            #endregion
     
            #region 还原ChnCharInfo.dll的所有静态方法
            /// <summary>
            /// 检索具有指定笔画数的字符个数。
            /// </summary>
            /// <param name="strokeNumber"></param>
            /// <returns></returns>
            public static short GetCharCount(short strokeNumber)
            {
     
                return (short)getChineseCharMethod("GetCharCount",
                    new Type[1] { strokeNumber.GetType() }).Invoke(null, new object[] { strokeNumber });
            }
     
            /// <summary>
            /// 获取给定拼音的所有同音字。 
            /// </summary>
            /// <param name="pinyin">拼音,指出读音。</param>
            /// <returns>返回具有相同的指定拼音的字符串列表。 如果拼音不是有效值则返回空。</returns>
            public static char[] GetChars(string pinyin)
            {
                return (char[])getChineseCharMethod("GetChars",
                    new Type[1] { pinyin.GetType() }).Invoke(null, new object[] { pinyin });
            }
     
            /// <summary>
            /// 检索具有指定笔画数的所有字符串。 
            /// </summary>
            /// <param name="strokeNumber">指出需要被识别的笔画数。</param>
            /// <returns>返回具有指定笔画数的字符列表。 如果笔画数是无效值返回空</returns>
            public static char[] GetChars(short strokeNumber)
            {
                return (char[])getChineseCharMethod("GetChars",
                   new Type[1] { strokeNumber.GetType() }).Invoke(null, new object[1] { strokeNumber });
            }
     
            /// <summary>
            /// 检索具有指定拼音的字符数。
            /// </summary>
            /// <param name="pinyin">显示需要被识别的拼音字符串。</param>
            /// <returns>返回具有指定拼音的字符数。 如果拼音不是有效值则返回-1。 </returns>
            public static short GetHomophoneCount(string pinyin)
            {
                return (short)getChineseCharMethod("GetHomophoneCount",
                    new Type[1] { pinyin.GetType() }).Invoke(null, new object[1] { pinyin });
            }
     
            /// <summary>
            /// 检索指定字符的笔画数
            /// </summary>
            /// <param name="chnChar">指出需要识别的字符。</param>
            /// <returns>返回指定字符的笔画数。如果字符不是有效值则返回-1。</returns>
            public static short GetStrokeNumber(char chnChar)
            {
                return (short)getChineseCharMethod("GetStrokeNumber",
                   new Type[1] { chnChar.GetType() }).Invoke(null, new object[] { chnChar });
            }
     
            /// <summary>
            /// 识别给出的两个字符是否是同音字。
            /// </summary>
            /// <param name="chnChar1">指出第一个字符</param>
            /// <param name="chnChar2">指出第二个字符</param>
            /// <returns></returns>
            public static bool IsHomophone(char chnChar1, char chnChar2)
            {
                return (bool)getChineseCharMethod("IsHomophone",
                   new Type[2] { chnChar1.GetType(), chnChar2.GetType() }).
                     Invoke(null, new object[2] { chnChar1, chnChar2 });
            }
     
            /// <summary>
            /// 识别给出的字符是否是一个有效的汉字字符。
            /// </summary>
            /// <param name="chnChar">显示需要被识别的笔画数。</param>
            /// <returns>返回具有指定笔画数的字符数。 如果笔画数是无效值返回-1</returns>
            public static bool IsValidChar(char chnChar)
            {
                return (bool)getChineseCharMethod("IsValidChar",
                    new Type[1] { chnChar.GetType() }).Invoke(null, new object[1] { chnChar });
            }
     
            /// <summary>
            /// 识别给出的拼音是否是一个有效的拼音字符串。 
            /// </summary>
            /// <param name="pinyin">指出需要识别的字符串。</param>
            /// <returns>如果指定的字符串是一个有效的拼音字符串则返回ture,否则返回false。</returns>
            public static bool IsValidPinyin(string pinyin)
            {
                return (bool)getChineseCharMethod("IsValidPinyin",
                    new Type[1] { pinyin.GetType() }).Invoke(null, new object[1] { pinyin });
            }
     
            /// <summary>
            /// 识别给出的笔画数是否是一个有效的笔画数。 
            /// </summary>
            /// <param name="strokeNumber">指出需要识别的笔画数。</param>
            /// <returns>如果指定的笔画数是一个有效的笔画数则返回ture,否则返回false。</returns>
            public static bool IsValidStrokeNumber(short strokeNumber)
            {
                return (bool)getChineseCharMethod("IsValidStrokeNumber",
                   new Type[1] { strokeNumber.GetType() }).Invoke(null, new object[1] { strokeNumber });
            }
     
     
            #endregion
     
            #endregion
     
            #endregion
            #endregion
        }
    }

    然后ChinaConverter类更简单
    /**********************************创建记录**********************************
      类  描述: 此类通过反射实现嵌入的资源ChineseConverter.dll里面的ChineseConverter类
      类    名: ChinaConverter
      创建  者:yj.zhou
      创建日期:2017/12/13 星期三 14:52:59
      类  说明: 参考ChinaChar类说明
    *******************************************************************************/
     
    using System;
    using System.Reflection;
     
    namespace OperateClass.Conver
    {
        /// <summary>
        /// 存储转换方向,包括繁体转换为简体中文和简体转换为繁体中文。
        /// </summary>
        public enum ChineseConversionDirection
        {
            /// <summary>
            /// 把简体中文转换为繁体中文。
            /// </summary>
            SimplifiedToTraditional = 0,
     
            /// <summary>
            /// 把繁体中文转换为简体中文。
            /// </summary>
            TraditionalToSimplified = 1
        } 
     
        /// <summary>
        /// 此类通过反射实现嵌入的资源ChineseConverter.dll里面的ChineseConverter类
        /// </summary>
        public class ChinaConverter
        {
            #region 静态方法
            /// <summary>
            /// 转换简体中文和繁体中文字符串。
            /// </summary>
            /// <param name="text">需要转换的字符串</param>
            /// <param name="direction">转换方向.</param>
            /// <returns></returns>
            public static string Convert(string text, ChineseConversionDirection direction = ChineseConversionDirection.SimplifiedToTraditional)
            {
                Type ChineseConverterType = null;
                Type ChineseConversionDirectionType = null;            
                Assembly ab = Assembly.Load(QuoteDll.ChineseConverter);
                foreach (Type item in ab.GetTypes())
                {
                    if (item.IsEnum && item.Name == "ChineseConversionDirection")
                    {
                        ChineseConversionDirectionType = item; 
                    }
                    if (item.IsClass && item.Name == "ChineseConverter")                 {                     ChineseConverterType = item;                 }
    if (ChineseConverterType != null && ChineseConverterType != null)
                       break;
                }            
                //if(ChineseConverterType == null || ChineseConversionDirectionType == null)            
                // new ArgumentNullException("不能获取资源文件定义的ChineseConverter类");
     
                object[] parame = new object[2] { text, (int)direction };
                object obj = ChineseConverterType.GetMethod("Convert").Invoke(null, parame);
                return (string)obj;
            }
            #endregion
     
        }
    }
    

     现在看看测试代码吧,完全没问题.

    private void btnChinaChar_Click(object sender, EventArgs e)
     {
         string ss = ChinaConverter.Convert("简体字,繁體字");
         ss = ChinaConverter.Convert("我写简体字");
         ss = ChinaConverter.Convert("你寫繁體字", ChineseConversionDirection.TraditionalToSimplified);
         ss = ChinaConverter.Convert("全都是汉字,哈哈!%$^&");
     
         bool b = ChinaChar.IsValidChar('万');//true
         short s = ChinaChar.GetCharCount(5);//319
         char[] ca = ChinaChar.GetChars("mo4"); //总共73个
         int ipy = ChinaChar.GetHomophoneCount("mo4");//73
         int ibh = ChinaChar.GetStrokeNumber('万');
         bool btyz = ChinaChar.IsHomophone('万', '莫'); //true
         ChinaChar chnChar = new ChinaChar('万'); }

    把这两个类编译成Dll,以后其它的项目里面也不需要再添加这两个dll引用了,

    通过相同的原理,做单exe程序也没啥问题了,哈哈.

    接下来我就是去丰富这个基础类.实现获取汉字首拼和切换简繁体了.

  • 相关阅读:
    静态字段==全局变量
    异常处理原则
    结合冒泡排序学习委托和事件系列一
    Linq详解
    linq的延迟执行和立即执行
    统计一个目录下所有.cs文件的行数
    Multicast委托和Observer模式——委托系列二
    usb设备插入电脑,电脑显示MTP带有黄色感叹号,(Windows已找到设备的去驱动程序,但在尝试安装他们时遇到错误),解决办法
    博客地址变更
    Flex在线阅读 FlexBook FlexPaper
  • 原文地址:https://www.cnblogs.com/span06/p/8042699.html
Copyright © 2011-2022 走看看