编译

首先了解下,如何区分编译生成的 .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()中的参数可以按需控制。

C# - 反射与编译的更多相关文章

  1. Java学习:注解,反射,动态编译

    狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解  什么是注解 ? Annotat ...

  2. 【UE4】基础概念——文件结构、类型、反射、编译、接口、垃圾回收、序列化

    新标签打开或者下载看大图 思维导图 Engine Structure Pipeline Programming Pipeline Blueprint Pipeline

  3. 初识Scala反射

    我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...

  4. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  5. 【C#进阶系列】23 程序集加载和反射

    程序集加载 程序集加载,CLR使用System.Reflection.Assembly.Load静态方法,当然这个方法我们自己也可以显式调用. 还有一个Assembly.LoadFrom方法加载指定路 ...

  6. java 面向对象编程-- 第十三章 反射、类加载与垃圾回收

    1.狭义JavaBean规范 Javabean必须包含一个无参数的public构造方法,方便通过反射的方式产生对象. 属性必须都是私有的. Javabean必须包含符合命名规范的get和set方法,以 ...

  7. 浅说Java中的反射机制(二)

    写过一篇Java中的反射机制,不算是写,应该是抄了,因为那是别人写的,这一篇也是别人写的,摘抄如下: 引自于Java基础--反射机制的知识点梳理,作者醉眼识朦胧.(()为我手记) 什么是反射? 正常编 ...

  8. 初识Java反射

    要详细的了解Java反射,就得要了解Java的类加载以及何为运行时动态加载等等概念.本文抛开其余概念,简单介绍Java反射,详细介绍会在以后有一个系统而全面的认识过后展开. 反射是Java被视为动态语 ...

  9. .NET Core单文件发布静态编译AOT CoreRT

    .NET Core单文件发布静态编译AOT CoreRT,将.NET Core应用打包成一个可执行文件并包含运行时. 支持Windows, MacOS and Linux x64 w/ RyuJIT ...

随机推荐

  1. Devexpress VCL Build v2014 vol 14.2.4 发布

    What's New in 14.2.4 (VCL Product Line)   New Major Features in 14.2 What's New in VCL Products 14.2 ...

  2. 前端之JavaScript笔记4

    一 按键事件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  3. POP介绍与使用实践(快速上手动画)[转]

    前言 动画在APP开发过程中 大家多多少少都会接触到 而且随着ios7的扁平化风格启用之后 越来越多的APP开始尝试加入各种绚丽的动画交互效果以增加APP的用户体验(当然 还是以国外的APP居多) 有 ...

  4. OpenGl 中的基本数据类型

    OpenGl 中的基本数据类型 为了便于 OpenGL在各种平台上移植,OpenGL定义了自己的数据类型. 如果你愿意也可用这些数据类型对应的标准C的数据类型来替代.如OpenGL也定义 GLvoid ...

  5. MFC中开发ocx控件,html容器收不到ocx的事件Event

    问题背景: MFC开发ocx控件,主窗口就是ctrl类,主窗口类中调度接口和事件映射添加,执行OK,外部html容器中接收事件成功,如下: ctrl.h中声明事件映射函数 void EVTPENSIG ...

  6. hdu 1014

    我:题都看不懂 路人甲:这是随机数分配题目 路人乙:这是求生成元,求mod N的生成元,即生成元与N互质 路人丙:这是根据给出的递推公式算一下 0~ mod-1之间的数是否都有出现过,如果都出现了,那 ...

  7. maven镜像

    使用maven管理项目,下载依赖jar包的时候,经常会下载很慢,但是如果使用镜像的话,速度超级快~~只要在.m2/setting.xml文件中设置镜像就可以啦~ 本文来自https://yq.aliy ...

  8. ios开发 ad hoc怎么用

    简单的说就是这样 ad hoc 方式是苹果用来给未上线的app做测试用的,首先你要在苹果开发平台上申请一个ad hoc的证书,再在profile中生成一个ad hoc 的profile文件(只需要在生 ...

  9. Delphi Dll 动态调用例子(2)

    http://zhidao.baidu.com/question/157196792.html delphi动态调用DLL 写了个1.dll内容如下 library Project2; uses Sy ...

  10. 使用 X-Frame-Options 防止被iframe 造成跨域iframe 提交挂掉

     Refused to display 'http://www.***.com/login/doLogin.html' in a frame because it set 'X-Frame-Optio ...