zoukankan      html  css  js  c++  java
  • C#

    编译

    首先了解下,如何区分编译生成的 .dll的版本
    方法1:ILSpy反编译工具

    通过 assembly属性,release版本没有或仅有如下一种属性

    [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
    

    而 debug版本,属性较多,示例

    [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | 
    DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
    

    具体参见:https://blog.csdn.net/WPwalter/article/details/80933080

    方法2:代码检测

    public static class Utils
    {
        //新增扩展方法
        public static T GetCustomAttribute<T>(this ICustomAttributeProvider provider)
            where T : Attribute
        {
            var attributes = provider.GetCustomAttributes(typeof(T), false);
            return attributes.Length > 0 ? attributes[0] as T : default(T);
        }
    
        public enum DllMode { Debug = 0, Release = 1 };
            
        public static DllMode CheckDllMode_1(string _filePath)
        {
            var assembly = Assembly.LoadFile(_filePath);
            var attributes = assembly.GetCustomAttributes(typeof(DebuggableAttribute), false);
            if (attributes.Length > 0)
            {
                var debuggable = attributes[0] as DebuggableAttribute;
                if (debuggable != null) {
                    return ((debuggable.DebuggingFlags & DebuggableAttribute.DebuggingModes.Default)
                                == DebuggableAttribute.DebuggingModes.Default)
                    ? DllMode.Debug : DllMode.Release;
                } else { return DllMode.Release; }
            } else { return DllMode.Release; }
        }
            
        public static DllMode CheckDllMode_2(string _filePath)
        {
            Assembly ass = Assembly.LoadFile(_filePath);
            DebuggableAttribute att = ass.GetCustomAttribute<DebuggableAttribute>();
            return (att != null && att.IsJITTrackingEnabled) ? DllMode.Debug : DllMode.Release;
        }
            
    } 
    

    具体参见:https://www.oschina.net/code/snippet_12_8459

    新增扩展方法时,若提示: 缺少编译器要求的成员“system.Runtime.CompilerServices.ExtensionAttribute..ctor”
    解决方法,在当前.cs中添加

    namespace System.Runtime.CompilerServices {
        public class ExtensionAttribute : Attribute { }
    }

    反射

    类Assembly中Load, LoadFrom, LoadFile方法比较

    下面给出2种程序集加载方法

    //方法1:直接从DLL路径加载 ok
    assembly = Assembly.LoadFrom(assemblyPath);
    
    //方法2:先把DLL加载到内存,再从内存中加载 ok
    using (FileStream fs = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read))
    {
    	using (BinaryReader br = new BinaryReader(fs))
    	{
    		byte[] bFile = br.ReadBytes((int)fs.Length);
    		br.Close();
    		fs.Close();
    		assembly = Assembly.Load(bFile);
    	}
    }
    

    可以将程序集中定义的所有类型暂存备用,调用时指定程序集和方法名即可

    // htTypes是Hashtable
    foreach (Type tp in assembly.GetTypes()) {
        htTypes.Add(tp.Name, tp);
    }                
    
    
    string className = "Calculator.Calculator"; //程序集.类名
    string funName = "Add";                     //方法名
    if (TypeTest.htTypes.ContainsKey(className))
    {
        var tp = (Type)TypeTest.htTypes[className];
        var func = tp.GetMethod(funName);
        if (null != func)
        {
            func.Invoke(null, new object[] { ... });
        }
    }
    

    对于设置或获取字段或属性的值,注意区分静态/非静态

    非静态的实例字段或属性,GetValue和SetValue时,第一个参数务必传入实例对象

    object obj = Activator.CreateInstance(type, true);
    

    而静态的,直接送null即可。设置时,保险起见可以作类型转换

    var v = Convert.ChangeType(value, tp.GetField/GetProperty(_name).FieldType/PropertyType);
    

    注,待加载的程序集可以在配置文件中配置。

      <configSections>
        <section name="assembly" type="System.Configuration.NameValueSectionHandler"/>
      </configSections> 
      
      <!-- key为程序集名称,value表示是否要加载 -->
      <assembly>
        <add key="Calculator.dll" value="1"/>
        <add key="crudHelper.dll" value="1"/>
      </assembly>
    

    代码中动态加载即可

    NameValueCollection assemblyList = ConfigurationManager.GetSection("assembly") as NameValueCollection;
    

    .Net框架提供了一个综合性方法:Type.InvokeMember,但是参数较多,慎用。

    应用

    [1]. 获取当前执行的方法的信息:2种

    MethodBase method = MethodBase.GetCurrentMethod();
    string tag = method.ReflectedType.FullName + "." + method.Name; //类名.方法名
    
    StackTrace stackTrace = new StackTrace(true);
    MethodBase method = stackTrace.GetFrame(0).GetMethod();
    string codeDestination = method.DeclaringType.Name + "-" + method.Name; //类名.方法名 
    

    若要获取父方法的信息,使用 GetFrame(1) 即可。

    [2]. 提取类实例字段名和字段值

    public static string GetAllKeyValue<T>(T t, IDictionary<string, object> dic, bool removeEmptyVal)
    {
        if (t == null || dic == null) { return "t||dic null"; }
    
        try {
            System.Reflection.PropertyInfo[] properties = t.GetType().GetProperties(
                System.Reflection.BindingFlags.Instance | 
                System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
            if (properties.Length <= 0) { return "properties 0"; }
    
            foreach (System.Reflection.PropertyInfo item in properties) {
                string name = item.Name;
                object value = item.GetValue(t, null);
    
                if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String")) {
                    if (removeEmptyVal && (value == null || 
                        (value is string && string.IsNullOrWhiteSpace(value.ToString())))) { /* not save empty value */ }
                    else { dic.Add(name, value); }
                } else {
                    GetAllKeyValue(value, dic, removeEmptyVal);
                }
            }
        } catch (Exception ex) {
            return ex.Message + "||" + ex.StackTrace;
        }
        return string.Empty;
    }
    

    其中GetProperties()中的参数可以按需控制。

  • 相关阅读:
    Java知识点:javac命令
    Java知识点:内部类
    证明:寝室分配问题是NPC问题
    Java知识点:Object类
    Java 知识点:序列化
    Python3玩转儿 机器学习(2)
    Python3玩转儿 机器学习(1)
    python re模块findall使用
    百度URL 部分参数
    python datetime模块
  • 原文地址:https://www.cnblogs.com/wjcx-sqh/p/10500484.html
Copyright © 2011-2022 走看看