1.3 初始询问非非确定性信号和槽,1.3方始摸底频域信号

一、.net和C#是什么关系

IL初步了解,初步了解英文

 

一、概述:

   
 近来也是在看AOP方面的东西,了解到Emit可以实现。之前对Emit的了解也就是停留在Reflector针对方法反编译出来的部分指令。就用这次机会学习下Emit也用这篇随笔记录下学习的过程。某些我也不了解的地方也希望各位了解的朋友指导下。

     学习前可以先了解下Opcodes

二、工具

1、vs2015

2、.NET Reflector 9.0

三、入门示例

1、输出Hello World

C#代码

图片 1

        static void Main(string[] args)
        {
            Console.WriteLine("Hello world!");
        }

View Code

反编译获取到的IL代码

图片 2

Emit实现代码

图片 3

        public void HellowWorld()
        {
            //定义Hellow方法没有返回值没有参数
            DynamicMethod helloWorldMethod = new DynamicMethod("HellowWorld", null, null);

            //创建IL,动态生成代码
            ILGenerator IL = helloWorldMethod.GetILGenerator();
            //将输出推送到堆栈上
            IL.Emit(OpCodes.Ldstr, "Hello World!");
            //执行Console.WriteLine
            IL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            //方法结束
            IL.Emit(OpCodes.Ret);
            HelloWordDelegate Method = (HelloWordDelegate)helloWorldMethod.CreateDelegate(typeof(HelloWordDelegate));
            Method();
        }

View Code

 
委托调用过程中。如果有参数会提示“操作可能破坏运行时稳定性”。(没弄清楚)

四、构建程序集

1、下面通过构建一个类里面包含两个方法来做实例

图片 4

        public int Add(int a, int b)
        {
            return a + b;
        }

        public string AddList(string[] array)
        {
            string result = string.Empty;
            for (int i = 0; i < array.Length; i++)
            {
                result = result + array[i];
            }
            return result;
        }

View Code

2、看下两个方法反编译出来的IL代码

图片 5

图片 6

下面我们来看看这段IL到底是如何实现的

●L0000到L0009:将string.Empty赋值给自定义变量resultName,加载整数0,L0009跳转到L001b执行
●L001b到L0027:加载1处索引值,加载参数1(静态从0开始),Ldlen将数组数目从0开始推送到堆栈上,对比两个数值的大小,(将对比结果存储到索引2处,然后再取出(这步实现中可省略)),然后跳转L_000b执行
●L000b到L001a:加载0处索引值,加载参数1,Ldelem_Ref用来加载string类型元素,执行string.concat方法,将值存储到索引0处,加载索引1处值,加载整数1,两值相加,将值存储到索引0处
●L002a结束返回

3、下面我们通过Emit代码来实现

图片 7

        public void GenerateAssembly()
        {
            string name = "IL.Dynamic";
            string fileName = string.Format("{0}.dll", name);

            //构建程序集
            AssemblyName assemblyName = new AssemblyName(name);
            //应用程序集域
            AppDomain domain = AppDomain.CurrentDomain;
            //实例化一个AssemblyBuilder对象来实现动态程序集的构建
            AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);

            //定义模块(不加filename为瞬态模块,不持久)
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(name);

            //定义类型
            TypeBuilder typeBuilder = moduleBuilder.DefineType(name, TypeAttributes.Public);

            //定义一个Add方法进行简单的相加
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("Add", MethodAttributes.Public, typeof(Int32), new Type[] { typeof(int), typeof(int) });

            //IL实现
            ILGenerator IL = methodBuilder.GetILGenerator();
            IL.Emit(OpCodes.Ldarg_1);
            IL.Emit(OpCodes.Ldarg_2);
            IL.Emit(OpCodes.Add);
            IL.Emit(OpCodes.Ret);


            //定义一个AddList字符串用for拼接方法
            MethodBuilder method2Builder = typeBuilder.DefineMethod("AddList", MethodAttributes.Public| MethodAttributes.Static, typeof(string), new Type[] { typeof(string[]) });
            FieldBuilder fieldName = typeBuilder.DefineField("resultName", typeof(string), FieldAttributes.Private | FieldAttributes.Static);
            ILGenerator addIL = method2Builder.GetILGenerator();

            //用来保存求和结果的局部变量
            LocalBuilder resultStr = addIL.DeclareLocal(typeof(String));
            ////循环中使用的局部变量
            LocalBuilder i = addIL.DeclareLocal(typeof(Int32));

            Label concatLabel = addIL.DefineLabel();
            Label LoopLabel = addIL.DefineLabel();

            //设置string result = string.Empty;
            addIL.Emit(OpCodes.Ldsfld, fieldName);
            addIL.Emit(OpCodes.Stloc_0);
            //设置i=0
            addIL.Emit(OpCodes.Ldc_I4_0);
            addIL.Emit(OpCodes.Stloc_1);
            addIL.Emit(OpCodes.Br, concatLabel);

            //进入循环体
            addIL.MarkLabel(LoopLabel);
            addIL.Emit(OpCodes.Ldloc_0);
            //参数指定静态从0开始
            addIL.Emit(OpCodes.Ldarg_0);
            addIL.Emit(OpCodes.Ldloc_1);
            //Ldelem_Ref用来加载string 类型元素
            addIL.Emit(OpCodes.Ldelem_Ref);
            addIL.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            addIL.Emit(OpCodes.Stloc_0);
            addIL.Emit(OpCodes.Ldloc_1);

            //i++
            addIL.Emit(OpCodes.Ldc_I4_1);
            addIL.Emit(OpCodes.Add);
            addIL.Emit(OpCodes.Stloc_1);

            addIL.MarkLabel(concatLabel);

            addIL.Emit(OpCodes.Ldloc_1);
            addIL.Emit(OpCodes.Ldarg_0);
            addIL.Emit(OpCodes.Ldlen);
            addIL.Emit(OpCodes.Conv_I4);
            //Clt比较两值大小
            addIL.Emit(OpCodes.Clt);
            addIL.Emit(OpCodes.Brtrue_S, LoopLabel);

            addIL.Emit(OpCodes.Ldloc_0);
            addIL.Emit(OpCodes.Ret);



            Type type = typeBuilder.CreateType();
            assemblyBuilder.Save(fileName);

            int[] ints = new int[] { 1, 2, 3, 4 };
            string[] array = new string[] { "a", "b", "c" };
            object ob = Activator.CreateInstance(type);
            var result = type.GetMethod("Add").Invoke(ob, new object[] { 8, 9 });
            var result1 = type.GetMethod("AddList").Invoke(ob, new object[] { array });
        }

View Code

3.1、AssemblyBuilderAccess

Run 可以执行但不能保存
Save 保存但不能执行
RunAndSave 可以执行并保存
ReflectionOnly 只反射上下文中加载

 

 

 

4、运行输出

4.1、生成文件

图片 8

借助工具反编译查看IL生成的C#代码

图片 9

4.2、运行结果

图片 10

 通过这个实例对IL可以有了比较基础的了解,在之后的学习中再慢慢喝大家进行交流。项目下载System.IL

一、概述:
近来也是在看AOP方面的东西,了解到Emit可以实现。之前对Emit的了解也就是停留在Reflector针对方法反…

  1. 什么是css语法?
    CSS (Cascading Style Sheets) 层叠样式表,用来编辑 HTML中元素的样式。
  2. 列举常见的css选择器?
    id、class
  3. background属性如何简写?
    将background 的所有属性写在一起,中间由空格键隔开,如下:
    background: red url() 20px 20px;
  4. 文本的属性有哪些?请写出font的复合式写法?
    Indent.align.decoration. Letter-spacing.word-spacing
    Font-weight font-style font-size/line-height font-family
  5. text-indent有什么作用?
    缩进
  6. 超链接a标签的作用有哪些?
    跳转页面。压缩包下载。跳到id所在位置。
  7. a标签默然样式是什么?
    <a herf=””></a>
  8. 什么是盒模型?盒模型包括什么?
    盒模型就是一个模块,呦一个大盒子套小盒子,盒模型包括外边距、边框、内边距。
  9. padding和margin的区别?
    Padding 是在边框以内、内容以外的
    Margin 则是在边框以外的并且有叠加和传递
  10. 什么是margin叠加?什么是margin传递?
    相邻两个元素之间的上下margin 会叠加。
    子元素的上下margin 会传递给夫集。
  11. 列举几种常见的语义化标签?
    Section heaader footer article aside……
  12. 常见的块元素和内嵌元素有哪些?简要说一下它们的区别?
    块元素(block
    element)一般是其他元素的容器元素,能容纳其他块元素或内联元素。常见的块元素:div、h1-h6标题等。内嵌元素(inline
    element)只能容纳文本或者其他内联元素,常见内联元素有a和span。
    块元素与内联元素的区别:
    1.块元素,总是在新行上开始;内联元素,和其他元素都在一行上。
    2.块元素,能容纳其他块元素或内联元素;内联元素,只能容纳文本或者其他内联元素。
    3.块元素中高度,行高以及顶和底边距都可控制;内联元素中高,行高及顶和底边距不可改变。

1.3 初步了解信号和槽,1.3初步了解信号

在Qt中,如何响应动作。这会用到Qt的信号和槽机制。

我的理解:它和Win32程序的消息响应机制差不多吧。

信号,简单理解就是:当我们点击一个按钮时,这个按钮自身就会产生一个叫作”单击”的信息,这个信息说明了刚刚我们点击了这一个按钮。产生的这个信息就相当于自己发射了一个信号,表明一个用户动作已经发生了或者是一个状态已经改变了。这就是信号(signal)。

槽,可以理解为:当这个按钮发射了这个信号之后,假如有一个”监听员”发现了这个信号,它会马上做出响应,做相应的动作。这个动作一般就是指执行一个或多个函数。这些就是槽(slot)。

要使得槽能够响应指定的信号,就需要把信号和指定的槽连接起来。连接之后,只要出现了这个信号,槽就会自动执行。

 

接下来看一下以下代码:

图片 11

第7行:创建一个QPushButton对象,头文件<QPushButton>

用到的函数:QPushButton::QPushButton ( const QString &
text**, QWidget * parent = 0 )**

函数的说明:构造一个文本为text的按钮,parent是它的父窗口,默认为0。

第9行:将信号(clicked())和槽(quit())连接。

用到的函数:bool QObject::connect ( const QObject *
sender**, const char * signal, const QObject *
receiver
, const char * method, Qt::ConnectionTypetype= Qt::AutoConnection )**

函数的说明:创建一个指定类型(type)的连接,指定发送方对象和方法,和接收方对象和方法。如果连接成功,返回true,否则将返回false。

参数中,type已经有默认值,现在来说不需要自己指定。

sender是发射信号的对象,signal是这个对象发射的具体的信号,需要使用SIGNAL()宏。

receiver是接收信号的对象,method是槽,也就是响应的函数,需要使用SLOT()宏。

 

SIGNAL()和SLOT()是Qt中定义的宏,这两个宏会把它们的参数转换成相应的字符串。

两个宏的参数都是不带参数名的函数名(参数名是指函数参数中的变量名,不是指参数类型,这其实也可以说成这两个宏的参数就是一个比较类似函数指针的类型的东西吧?只不过没有返回值和返回值后面跟着的(*)这个东西而已)。

sender与receiver对象各自拥自己的发射信号和槽,例如例子中QPushButton有clicked()信号和QApplication有quit()槽。

 

QPushButton的信号是通过继承而来的,它继承自QAbstractButton类,这个类本身拥有以下信号:

图片 12

分别有1个信号继承自QWidget、QObject。主要的还是上面4个信号。

看看就好~嘿嘿,自己也可以尝试。

 

QApplication的有以下槽:

图片 13

在例子中,使用了一个quit(),这个槽是QApplication继承自QCoreApplication类得到的。

在QCoreApplication中,定义了quit()这个槽。

 

例子中,clicked()信号表明当用户单击了按钮button时会发射的信号,然后执行app对象中的槽quit(),从而退出这个程序。

 

就暂时到这里吧,到这里,也算是初步了解了什么是信号和槽。这个是Qt编程的基础。

另外,Qt帮助文档也是一个不错的东西。

如果是使用Qt
Creator,想要知道某一个Qt类的详细信息的话,单击一下类名,按F1就可以转到帮助文档了。

 

在我看来,信号和槽进制比较好理解,简单地想成是一个发送方和接收方就行了,当点击按钮时,发送方发送一个clicked()的消息给接收方,接收方接收消息之后开始做自己的动作。

 

当然了,毕竟只是自己的总结笔记,有些地方是自己理解来写的,如果理解是错误的请见谅~

初步了解信号和槽,1.3初步了解信号
在Qt中,如何响应动作。这会用到Qt的信号和槽机制。
我的理解:它和Win32程序的消息响应机制差不…

初步了解javascript面向对象,初步了解javascript

前言

基于类的对象:我们都知道面向对象的语言中有一个明显的标志,就是都有类的概念,通过类这个类似模板的东西我们可以创建许多个具有相同的属性和方法的对象。然而在ECMAScript中并没有类的概念,自然它与基于类的语言中的对象也会有所不同。

js中的对象: 无序
的属性的集合,属性可以包含基本值、对象、函数。即js中的对象是一组没有特定顺序的值,对象的每个属性或者方法都有一个自己的名字,而每个名字都与一个值相对应。

理解对象

创建对象的方式

1
创建一个对象的最简单的方式是创建一个Object实例,之后为其添加属性和方法。

例如

  var person = new Object();
    person.name='谦龙';
    person.sex='男';
    person.sayNameAndSex=function(){
      console.log(this.name,this.sex)
    }
    person.sayNameAndSex(); // 谦龙 男

2 使用对象字面量形式

例如

  var person={
    name:'谦龙',
    sex:'男',
    sayNameAndSex:function(){
      console.log(this.name,this.sex)
    }
  }
   person.sayNameAndSex(); // 谦龙 男

属性的类型

ECMAScript有两种数据属性:数据属性和访问器属性。

数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。共有四个描述其行为的特性。

1.[[Configurable]]:表示能否通过delete删除属性从而重新定义属性…默认值为true

2.[[Enumerable]]:表示能否通过for in 循环返回属性…默认为true

3.[[Writable]]:表示能否修改属性的值…默认为true

4.[[Value]]:表示这个属性的值.默认为undefined

要修改属性默认的特性,必须使用ES5的Object.defineProperty()方法,而该方法接收三个参数:属性所在的对象、属性的名称、还有一个描述属性特性的对象(configurable、enumerable、writable、value),设置其中的一个或者多个值可以修改对应的特性

DEMO

var person={};
Object.defineProperty(person,'name',{
 configurable:false,//表示不允许通过delete删除属性
 writable:false,//表示不允许重写
 ennumerable:false,//表示不允许通过for in遍历
 value:'谦龙'//设置该对象中属性的值
})
person.name='谦龙2';//尝试重新设置 结果不生效
delete person.name;//尝试删除 结果不生效
for(var attr in person){
 console.log(person[attr]);// false
}
console.log(person.name);//谦龙

注意:将 configurable 设置为false后
不允许再次修改为true,另外在调用Object.defineProperty()方法的时候,configurable、ennumerable、writable默认值为false。

访问器属性

访问器属性不包含数据值,它们包含一对getter、setter函数(但是这两个函数并不是必须的)在读取访问器属性的时候,会调用getter函数,这个函数是负责返回有效的值,在写入访问器属性的时候会调用setter函数并传入新值,这个函数负责如何处理数据。

访问器属性具有如下的特性

[[configurable]] 表示能否通过delete来删除属性从而定义新的属性

[[enumerable]] 表示能否通过for in循环来遍历返回属性

[[get]] 在读取属性时候调用的函数,默认为undefined

[[set]] 在写入函数的时候调用的函数,默认的值为undefined

注意:访问器属性不能直接定义,必须通过Object.defineProterty()定义

DEMO

 var book={
 _year:2015, //这里的下划线是常见的记号,表示只能通过对象的方法才能访问的属性
 edition:1
}
Object.defineProperty(book,'year',{
 get:function(){
  return this._year; //即默认通过 book.year获取值的时候 返回的是 boot._year的值
 },
 set: function (value) {//在对 boot.year设置值的时候 默认调用的方法 对数据进行处理
  var _year=this._year;
  if(value > _year){
   this._year=value;
   this.edition+=value-_year;
  }
 }
})
book.year = 2016;
console.log(book.year,book.edition); // 2016 2

定义多个属性

我们可以通过ES5中的Object.defineProperties()方法来给对象添加多个属性,该方法接受两个
对象
参数,第一个参数是要添加和修改其属性的对象,第二个对象的属性和第一个对象中要添加和修改的属性一一对应。

DEMO

var book={};
Object.defineProperties(book,{
 _year:{
  value:2015,
  writable:true //注意这里设置成true 才可以 "写" 默认是false 
 },
 edition:{
  value:1,
  writable:true //注意这里设置成true 才可以 "写" 默认是false
 },
 year:{
  get:function(){
   return this._year;
  },
  set: function (value) {
   var _year=this._year;
   if(value > _year){
    this._year=value;
    this.edition+=value-_year;
   }
  }
 }
})
book.year=2016;
console.log(book.year,book.edition); // 2016 2

读取对象属性的特性

使用ES5中的Object.getOwnPropertyDescriptor()方法,可以去的给定的属性的描述符。

该方法接收两个参数:属性所在的对象和要读取描述符的属性名称。返回的是一个对象,如果是数据属性,则返回的属性有
configurable,enumerable,writable,value.如果是访问器属性则返回的属性有
configurable,enumerable,get,set

DEMO

var book={};
Object.defineProperties(book,{
 _year:{
  value:2015,
  writable:true
 },
 edition:{
  value:1,
  writable:true
 },
 year:{
  get:function(){
   return this._year;
  },
  set: function (value) {
   var _year=this._year;
   if(value > _year){
    this._year=value;
    this.edition+=value-_year;
   }
  }
 }
})
//对象遍历函数
function showAllProperties(obj){
 for(var attr in obj){
  console.log(attr+':'+obj[attr]);
 }
}
var descriptor= Object.getOwnPropertyDescriptor(book,'_year');//数据属性
var descriptor2= Object.getOwnPropertyDescriptor(book,'year');//访问器属性
showAllProperties(descriptor);
console.log('============================');
showAllProperties(descriptor2);

以上关于初步了解javascript面向对象的全部内容就介绍到这里,下面将给大家介绍深入浅析js面向对象之详解常见创建对象的几种方式,感兴趣的朋友继续关注哦。

前言
基于类的对象:我们都知道面向对象的语言中有一个明显的标志,就是都有类的概念,通…

.net是一个程序运行的平台,它是c#,vb,F#等程序运行的平台,为这些语言提供基础类库、公共语言运行时等相关支持。

C#是支持.net的一种编程语言。.net编程语言有很多种,常用的是C#,还有Visual
Basic、C++/CLI、Eiffel、F#、IronPython等很多种。

visual studio是开发工具,支持这些编程语言开发相应的.net程序。

二、编译与执行

编译是把编程语言编写的源代码转成CIL并生成程序集的过程。执行是程序执行时CLR捕获CIL后,激活JIT编译器,将CIL编译成机器语言的过程。上一张抄来的图(

图片 14

三、名词解释

各种缩写,名词太多了,一直弄混,找一些经常看见的记录下。

1、CLR(Common Language
Runtime,公共语言运行库):CLR是一个运行时环境,功能主要包括内存管理,程序集加载,异常管理,系统资源回收等。

2、托管代码:由CLR管理运行的代码。

3、非托管代码:与CLR无关的代码。

4、GC(Garbage
Collector,垃圾收集器):GC只能回收托管资源(由CLR管理的存在于托管堆上的称为托管资源)。GC的运行不需要人工干预,CLR会在需要的时候调用GC进行垃圾回收。GC遍历托管堆上的对象,将不能回收的对象做上标记,最后没有标记的对象作为垃圾释放掉,释放后不连续的内存空间会压缩成连续的内存空间。

5、CIL(Common Intermediate
Lauguage,公共中间语言):与IL,MSIL是一个概念,源代码在编译过程中被翻译成的一系列指令集。CIL是底层平台无关的,CLR使用不同CPU的即时编译器编译CIL为相应的机器代码。

6、元数据:描述数据的数据。描述了文件中定义的类型以及每个类型的成员,比如某个字段的访问权限、字段拥有者等信息。

7、程序集清单:本身也是一种元数据,描述程序集自身。记录了关联的外部程序集、程序集版本、版权信息等。发布的程序运行提示哪个dll版本不匹配就是路径下的dll文件版本与清单中记录的版本不一致。

8、程序集:由编译成生成的dll、exe文件。包含CIL、元数据、清单的一种集合,是可以被CLR加载并运行的一堆数据集。(VS里创建的一个新项目,比如一个类库,编译后就被打包成与类库名称相同的一个dll,这就是一个程序集)。

9、CTS(Common Type
System,通用类型系统):一个正式的规范,规定了类型必须如何定义才能被CLR加载。主要是类、结构、枚举、委托、接口五中类型。system.Int32、system.Object等是内建的CTS数据类型。平时用的int
,string这些关键字是这些类型的一种代号。

10:CLS:一套规则,每种编程语言都有各自的语法,不同的语言功能,CLS就是一种能在各种语法中通用的一种准则。按照这个准则生成的程序集可以在其他语言中调用。

个人理解,后续慢慢补充完善。

相关文章