我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#中使用CLR需要注意什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#中使用CLR需要注意什么

这篇文章主要为大家展示了“C#中使用CLR需要注意什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#中使用CLR需要注意什么”这篇文章吧。

1、C# CLR之foreach的性能问题

foreach(string s in rows) { foo(s); }的实现是:

IEnumerator e = rows.GetEnumerator();  try {    string s;    while (e.MoveNext()) {      s = (String) e.Current;      foo(s);    }  }  finally {    IDisposable d = e as IDisposable;    if (d != null) d.Dispose();  }

每一步都调用了e.MoveNext()和e.Current两个方法;而大多数时候,完全有可能优化为一次调用。显然这对性能是有影响的。虽然foreach对于数组作了单独的优化(编译成for循环),但这还是值得注意的。

那么,怎么做比较快?

对于List等Collection,可以用ForEach(Actionaction),FindAll(Predicatematch),ConvertAll(Converterconverter)等方法。它们比较快,但不是所有实现IEnumerable的类都提供。

LINQ追求compatiblity,而不是performance。因此LINQ的实现完全采用了foreach。值得注意。

2、C# CLR之yield的实现原理

实现一个支持IEnumerable的对象时,一般会用到yield关键字,这样foreach遍历这个对象时,可以做到lazy evaluation。例如:

class MyCollection: IEnumerable<char> {    private string s; ...    public IEnumerable<char> GetEnumerator() {      for (int i=0; i<s.Length; i++)    {        yield return s[i];      }   }  }

执行到yield时函数返回,下次调用时,接着上次运行的位置继续运行。这个continuation的效果是怎么做的呢?

包含yield的函数都会被编译器做成一个状态机。每调一次,就接着上次的状态继续运行。简单有效啊。我一直以为要有什么特殊的办法呢。

3、C# CLR之exception handling的实现决定了throw的performance较差。

可以用Int32.TryParse代替try{Int32.Parse…}catch{…},稍快一点。类似地建议使用Dictionary.TryGetValue。

4、C# CLR之.Net CLR执行引擎对应于MSCorWks.dll和MSCorEE.dll这两个文件。

5、C# CLR之.Net 3.0, 3.5没有对CLR作任何修改。

所有增加的东西(比如LINQ)都是syntactic sugar,只改了C#编译器而已。

6、C# CLR之AppDomain

如果把.Net虚拟机看成一个虚拟操作系统,AppDomain的概念则类似于操作系统中的进程。

可以用代码创建一个AppDomain,然后动态加载/卸载assembly,还可以设置权限,相当于提供了一个沙箱。

跨AppDomain的调用类似于RPC。

调用某个AppDomain内部的obj.foo(x)时,.net会自动帮你做出一个proxy object,你所调用的obj其实是一个proxy object。传给foo的参数x会先被被marshal,以保证AppDomain被安全隔离。

谁用AppDomain?SQL Server用这个技术实现managed存储过程。IIS会把不同的Web Application放在不同的AppDomain里,以实现动态装卸。

7、C# CLR之动态载入Assembly的陷阱

Sytem.Reflection.Assembly.LoadFrom(pathName)并不会载入pathName所指定的dll,而是看看pathName那个dll的名字、版本,然后到系统默认位置去找。(陷阱啊)

8、C# CLR之C#里用reflection创建一个新对象

用Activator.CreateInstance。(奇怪的名字啊。)

9、C# CLR之C#泛型之“where”

可以用“where”来限定T的接口。例如

static T min(T arg1, T arg2) where T: IComparable{…}

不写where的话,就不能调arg1.CompareTo(arg2)。

为啥不把T换成IComparable?一是为保证arg1, arg2一定是同一个类型,二是泛型的效率更高。(JIT会为不同类型的T各生成一份native code,从而避免了boxing)

更多where的细节:

* 要想调T t1 = new T(),必须声明where T: new()或者where T: struct

* 要写T t2 = null,必须声明where T: class

* T z = default(T)是一个特殊的用法,会把T的每个bit都置为0。

* 假设定义了Foo(T x, T y),则if (x==null) … 是可以通过的,虽然C#中value type的值不允许为null(例如int a=null是错的)。这是因为,此时的语义是一致的,反正if里面的操作不被执行就是了,所以编译器对这种特殊情况网开一面。

* if (x==y)不行,除非写了where T: baseclass。(这里我也没理解为啥。。。>_<好像说是不知道应该用reference比较还是value比较?)

10、C# CLR之匿名函数的背后。。。

在C# 2.0以后可以用匿名的delegate,如ThreadPool.QueueWorkItem(delegate (Object obj) { Console.WriteLine(obj); })

但编译器的实现会带来一点点overhead,会生成一个小小的静态WaitCallback对象,可以用Reflector看生成的代码。(不要打开Reflector的optimization,否则就看不到了)

如果是自己写的话,可以选择每次动态建立一个WaitCallback对象然后销毁。当然这样做性能可能差一些,但这里的idea是:编译器会自动做一些事,但不一定是你所希望的。在使用这些高级feature前,最好先搞清楚背后发生了什么。

另一个细节:如果匿名函数中使用了外层函数的局部变量(即所谓的function closure),会导致创建额外的shared-state object,把用到的局部变量做成一个新对象传给匿名函数。

上述描述同样适用于lambda函数。因为C#的lambda函数就是匿名函数,改了改语法而已。

11、C# CLR之Nullable type

虽然C#要求value type的值不能是null,但写数据库程序时经常遇到某个值是null的情况。为此,C#2.0引入了Nullable type。例如,int? x = null。

int? x其实就是一个缩写,等价于Nullablex。Nullable是预定义的一个类,简单地对x作了封装。(因为增加了一个类,显然对性能稍微有点影响)

这个小改动的实现其实很麻烦,需要修改CLR。为什么?因为原先的x是一个value type,现在则变成了一个object,看这个:

void M(Object o)   {    if (o=null) {Bar();}  }  void F()  {    int? x = null;    M(x);  }

如果CLR不专门做修正的话,上面的Bar()不会被执行。(思考题:想一想为什么~)

另外,C#还引入了一个默认值运算符“??”,称为null-coalescing operator。

一句话,x ?? value是 (x==null) ? value: x的简写。

12、C# CLR之属性(property)的简单声明

public int x {get; private set;}

是个很好用的句式。

注意,

public int x {get;}

是错误的,不能通过编译。

13、C# CLR之Extension method

//Extension method  static class MyExtMethods   {    static public GetFirstLetter(this string s) {return s[0];}  }

然后就可以用string s = “hello”; char ch = s.GetFirstLetter()了。

原理很简单,编译器把上面那句话翻译成MyExtMethods.GetFirstLetter(s)。LINQ就用到了这个技术。

14、C# CLR之匿名类型的背后。。。

var o = new {name = “Xiangpeng”, id = 123 };

在这背后是编译器生成的一个匿名类,包含了两个只读属性,形如public int id { get {return _id;} }为什么不做成可读写的呢?

很微妙。匿名类自动生成了GetHashCode(),返回的是对所有属性的hash code做XOR的结果。如果允许修改属性值,那么Hash code的值就会变化;而这个可能会出问题~保险起见,只读吧。

15、C# CLR之每个thread占1M物理内存

在Win32编程中thread的1M stack空间是Reserve的,直到真正用时才占用物理内存;而在.net中,这1M空间直接被commit。

还好,可以在新建thread时指定stack size。不过这也比较危险,设小了怕不够。实际上,最好尽量避免创建thread——太多的thread要么导致CPU竞争和context switch,要么都block着浪费内存。建议是:能用ThreadPool就用ThreadPool。

以上是“C#中使用CLR需要注意什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C#中使用CLR需要注意什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#中使用CLR需要注意什么

这篇文章主要为大家展示了“C#中使用CLR需要注意什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C#中使用CLR需要注意什么”这篇文章吧。1、C# CLR之foreach的性能问题 fore
2023-06-17

java中CAS使用需要注意什么

这篇文章将为大家详细讲解有关java中CAS使用需要注意什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Queu
2023-06-14

使用ADO.NET时需要注意什么

小编给大家分享一下使用ADO.NET时需要注意什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!使用ADO.NET时,出现了一个严重的问题,ADO.NET统一了数
2023-06-17

C#连接Access需要注意什么

本篇内容介绍了“C#连接Access需要注意什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!C#连接连接Access的问题是如何解决的呢,
2023-06-17

c++中使用mfc框架要注意什么

在使用MFC框架开发C++应用程序时,需要注意以下几点:MFC类的命名规范:MFC中的类名前缀通常是C(例如CDialog、CButton),要遵循这种规范来命名自己的类。对话框资源的使用:MFC中的对话框资源用于创建用户界面,要熟悉对话框
c++中使用mfc框架要注意什么
2024-02-29

使用Linux桌面需要注意什么

这篇文章主要介绍使用Linux桌面需要注意什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!这个问题没有轻松的答案,如果你是新用户,之前没有用过任何Linux桌面,更是这样。围绕这个话题而写的文章大多数也没有多大帮助
2023-06-10

js使用语法需要注意什么

本篇内容介绍了“js使用语法需要注意什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明1、在js中严格区分大小写。其实这是用来排错的。正
2023-06-20

VS2003版本使用需要注意什么

这篇文章主要讲解了“VS2003版本使用需要注意什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“VS2003版本使用需要注意什么”吧!VS2005可以很方便的帮我们把VS2003开发的as
2023-06-17

C#类型转化需要注意什么

这篇文章给大家分享的是有关C#类型转化需要注意什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、as和is操作符都不执行任何用户自定义的转换。2、对于强制转换,引用为空将会转换出错。3、强制转换任意类型和自定
2023-06-17

python中使用私有方法需要注意什么

这篇文章将为大家详细讲解有关python中使用私有方法需要注意什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。python的五大特点是什么python的五大特点:1.简单易学,开发程序时,专注的是解决问
2023-06-14

mysql中使用覆盖索引需要注意什么

这篇文章主要介绍mysql中使用覆盖索引需要注意什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、使用注意(1)覆盖索引不适用于所有索引类型,索引必须存储列值。(2)Hash和full-text索引没有存储值,所
2023-06-15

C++ 函数设计需要注意什么?

遵循这些准则可以编写出健壮且易于理解和维护的 c++++ 函数:定义清晰的函数接口。保持函数单一职责。使用适当的数据类型。处理异常。文档化函数。C++ 函数设计准则C++ 函数设计是编写高效、可读和可维护代码的关键。以下是设计 C++ 函
C++ 函数设计需要注意什么?
2024-04-12

Xamarin.Forms使用Slider需要注意什么问题

这篇文章主要为大家展示了“Xamarin.Forms使用Slider需要注意什么问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Xamarin.Forms使用Slider需要注意什么问题”这篇
2023-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录