CLR VIA

时间:2021-07-11 16:25:27
 标题  状态  内容

什么是CLR?

什么是托管模块?

托管模块由什么组成?

。net代码的执行过程

 

http://www.cnblogs.com/aaa6818162/p/4726581.html

http://www.cnblogs.com/kingmoon/archive/2012/07/16/2594459.html

CLR VIA

CLR VIA

为了执行程序,首先必须把它的IL转换成本地CPU指令

CLR VIA

第二次调用WriteLine的情况

CLR VIA

PE文件   http://lwglucky.blog.51cto.com/1228348/283812/
 元数据的   http://www.cnblogs.com/bluewater/archive/2006/10/17/531639.html

元数据的逻辑结构类似于数据库中的表,所以被称为元数据表。元数据表有列和行,每一行都是不重复的,都有唯一的RID(表索引),RID就像是数据库表的主建。数据库有Schema,如每一列的类型,大小等,元数据也有类似的东西,他们被称为“元-元数据”,包含表中记录的大小,列的大小,偏移等。

.Net 托管模块与程序集的关系

   http://blog.csdn.net/kmguo/article/details/17055065
     

.NET概念:.NET程序编译和运行

 

http://blog.csdn.net/yysyangyangyangshan/article/details/7306346

应用程序域(AppDomain)。可以理解成很多应用程序域都可以运行在同一个.NET的进程中,可以降低系统消耗,同时不同的域之间互相隔离,在安全性方面有保障。另外对于同一个进程内不同域之间的通信也相对简单一点

   
  • 这段代码进行了几次装箱?

public static void Main() {

Int32 v = 5; // 创建值变量

Object o = v; // 装箱

v = 123; // Changes the unboxed value to 123

Console.WriteLine(v + ", " + (Int32) o); // Displays "123, 5" ,装箱两次

}

 验证四种判等方式  

①Object的静态方法ReferenceEquals:

 

只适用于判断两个引用是否指向同一个实例,不适用于值类型(或者说用于值类型是没意义的,因为永远返回false)。如下:

TestEqual te = new TestEqual();

bool b1= object.ReferenceEquals(te,te);

bool b2 = object.ReferenceEquals(1, 1);

b1为true,b2为false。b2为false的原因是两个整型值1装箱之后是两个不同的Object实例。

②Object中定义的实例级虚方法Equals:

 

其默认行为是判断引用是否相等,引用类型从Object中继承了这一行为,如下:

TestEqual te1= new TestEqual();

TestEqual te2 = new TestEqual();

bool b4= te1.Equals(te2);

bool b5 = te1.Equals(te1);

Console.WriteLine(b4);

Console.WriteLine(b5);

输出结果很明显第一个假,第二个真。

但是对于值类型来说,由于ValueType重写了这个方法,所以其行为不同,可以判断值是否相同,而不是引用。

如下:

int num1 = 15;

int num2 = 15;

bool b3 = num1.Equals(num2);

Console.WriteLine(b3);

虽然num1和num2是两个变量,但是只要它们的值一样,b3结果就为true。

③ = =运算符:

 

应用于值类型的时候其行为是判断值是否相等。应用于引用类型(String除外)的时候判断引用是否相同。

④Object中的静态方法Equals:

 

它接受两个Object类型的参数,它会调用第一个参数的实例级Equals方法,以第二个参数作为该方法的参数来进行判等。所以其行为表现出来和实例级的Equals方法一样。只是其内部添加了对于两个参加判等的参数是否本身已经是同一个引用的判断,还有两个参数是否为null的判断。

 常量const  

http://www.cnblogs.com/janes/archive/2011/07/11/2103215.html

常量是恒定不变的,在编译时就确定了它的值,编译后直接将值存到元数据中。变量类型只能是编译器能直接识别的基元类型,不能是引用类型,因为引用类型需要在运行时调用构造函数进行初始化。

通过ILDasm工具查看一下,const变量编译后为static literal类型,所以不难理解,常量是针对类的一部分,而不是实例的一部分

 只读字段readonly    类的数据成员通常用来保存一个值类型的实例或者指向引用类型的引用,CLR支持读写和只读两种数据成员,其中只读数据成员使用readonly修饰的
     其实很简单,C#中方法中的参数也是一个变量,这个变量也需要有一个地址。

对于引用类型的方法参数,传入的对象如果不加Ref,方法参数也就是这个变量也将被创建,不过因为是引用类型,所以地址直接指向所传入对象的地址。所以实际上是有两个变量,但都指向了同一处地址。
如果加了Ref,那么方法参数这个变量,将不被创建,也就是只有一个变量,指向了一处地址。

引用类型加不加Ref没有本质区别,只是多个了变量而已。

string/String类型作为参数是传值还是传址_AX

 

class Program
    {
        static void Swap(string a, string b)
{
            string c = a;
            a = b;
            b = c;
        }
       
        static void Main(string[] args)
        {
            string str1 = "Jenny";
            string str2 = "Benny";

Swap(str1, str2);

Console.WriteLine(str1);
            Console.WriteLine(str2);
            Console.Read();

}
    }

string在.net中是个特殊的对象,当把一个string传给一个方法时其实是做了一个“s=s”的操作,如果是其它对象,当然是前者得到后者的一个地址引用,而string对象每做一次赋值操作,被赋值的string都会重开一个内存空间将后者的值复制过来,所以才有了你的结果。
 
string类是引用类型,在赋值时是传址的。但如果用作函数参数的话系统会自动复制一个string类进行运算,因为函数默认是按值传递的。如果函数要传址,请在函数定义时,在参数前加上ref,在使用时也加上ref就可以了。

CLR VIACLR VIA{
 7CLR VIA    class TestString
 8CLR VIACLR VIA    CLR VIA{
 9CLR VIA        public static void Main()
10CLR VIACLR VIA        CLR VIA{
11CLR VIA            string s = "AX";
12CLR VIA            Change(s);
13CLR VIA            Console.WriteLine(s);
14CLR VIA            Console.ReadLine();
15CLR VIA        }
16CLR VIA
17CLR VIA        private static void Change(string s)
18CLR VIACLR VIA        CLR VIA{
19CLR VIA            s = "zhz";
20CLR VIA        }
21CLR VIA    }
22CLR VIA}

 C#友元程序集