C#高效编程话题集2(每期10话题)

简介: 第一期话题在:C#高效编程话题集1(每期10话题) C#快速成长团队第二期话题来到。欢迎进入C#快速成长团队进行讨论。 1:确保集合的线程安全 如果使用.net4.0,有新的线程安全集合类新的 System.Collections.Concurrent 命名空间引入了多个新的线程安全集合类,可在需要时随时提供对项的无锁访问,并在锁适用时提供细粒度锁定。

第一期话题在:C#高效编程话题集1(每期10话题)

C#快速成长团队第二期话题来到。欢迎进入C#快速成长团队进行讨论。

1:确保集合的线程安全

如果使用.net4.0,有新的线程安全集合类
新的 System.Collections.Concurrent 命名空间引入了多个新的线程安全集合类,可在需要时随时提供对项的无锁访问,并在锁适用时提供细粒度锁定。 在多线程方案中使用这些类应获得优于集合类型(例如, ArrayList 和 List <(Of <(T >)>))的性能。

除了System.Collections.Concurrent空间下集合外,非泛型集合使用
lock(非泛型集合对象.SyncRoot)进行锁定达到集合线程安全目的
泛型集合使用
static object sycObj = new object(); //是否static看具体应用
lock (sycObj)
{
     //操作集合。
}

2:循环中先求长度还是使用list.Count,哪个效率高

第一类:

int len = list.Count; 

for(int i; i<len; i++)

{

     迭代

}

第二类:

for(int i; i<list.Count; i++)

{

     迭代

}

答案是一样高。

第一种方法完全没有必要,很多人可能以为那样会为代码带来效率,而实际上是不会给效率带来任何提升。
因为事实上,索引器内部,为了安全期间,还是会去求整个list的count的。将两者代码贴出来可能会更好的理解这一点:
public T this[int index]
{
    get
    {
       if (index >= this._size)
      {
          ThrowHelper.ThrowArgumentOutOfRangeException();
      }
      return this._items[index];
    }
    set
    {
        if (index >= this._size)
        {
            ThrowHelper.ThrowArgumentOutOfRangeException();
        }
        this._items[index] = value;
        this._version++;
    }
}


public int Count
{
    get
    {
        return this._size;
    }
}

3:善用延迟求值

以List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};为例,说明linq查询中的延迟求值和主动求值。

List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var temp1 = from c in list where c > 5 select c;
var temp2 = (from c in list where c > 5 select c).ToList<int>();
list[0] = 11;
Console.Write("temp1: ");
foreach (var item in temp1)
{
    Console.Write(item.ToString() + " ");
}
Console.Write("\ntemp2: ");
foreach (var item in temp2)
{
    Console.Write(item.ToString() + " ");
}

4:谨慎泛型类型中的静态成员

static void Main(string[] args)
{
     MyList<int> list1 = new MyList<int>();
     MyList<int> list2 = new MyList<int>();
     MyList<string> list3 = new MyList<string>();
     Console.WriteLine(MyList<int>.Count);
     Console.WriteLine(MyList<string>.Count);
}
class MyList<T>
{
     public static int Count { get; set; }
     public MyList()
     {
         Count++;
     }

}

代码输出是莫子?

只要知道 MyList<int> 和 MyList<string> 是两个不同的类型,这题就不难理解了。.NET 中类型参数不同的封闭泛型类型是不同的类型。

5:小心闭包中的陷阱

for (int i = 0; i < 10; i++)
{
     Action t = () =>
    {
        Console.WriteLine("t1:" + i.ToString());
    };
    t.BeginInvoke(null, null);
}

以上代码的输出为?

当闭包中引用了外部的局部变量或者方法参数的时候,C#会把该变量编译成一个类的实例字段,顶楼的代码编译后实际上等效于:
TempClass tp = new TempClass();
for (tp.i = 0; tp.i < 10; tp.i++)
{
  Action t = tp.TempMethod;
  t.BeginInvoke(null, null);
}
TempClass是C#编译器自动生成的类,其定义大概是这样:
class TempClass
{
  public int i;
  public void TempMethod()
  {
    Console.Writeline("t1:" + i.ToString());
  }
}
因为只循环10次,几乎一瞬间就完了,因此第一个异步委托还没开始执行 tp.i 就等于10了

6:event关键字的作用

既然使用委托也能实现回调,为什么又需要event关键字。答曰:event 最大的作用就是防止在类的外部触发类的事件。

7:区分IEnumerable<T>和IQueryable<T>

本地数据源用IEnumerable<T>,远程数据源用IQueryable<T>。
针对LinqLINQ TO to OBJECTS,使用Enumerable中的扩展方法对本地集合进行排序、查询等操作,查询参数接受的是Func< >。Func< >叫做谓语表达式,相当于一个委托。针对LinqLINQ TO to SQL则使用Querable中的扩展方法,它接受的参数是Expression< >。Expression< >用于包装Func< >。LinqLINQ TO to SQL引擎最终会将表达式树转化成为相应的SQL语句,然后在数据库中执行。

  

8:选择正确的集合

查看此文吧:http://www.cnblogs.com/luminji/archive/2011/03/24/1993393.html

9:泛型参数的约束是不是应该叫约定更好

在泛型的使用过程中,常常使用到的一个功能就是为泛型参数设定约束。约束听上去像是限制了泛型参数的使用范围,而实际上,约束本身确实拓展了泛型参数的使用。

一个没有约束的泛型参数,只能具有object的行为和属性,而一个指定约束为Student的泛型参数,却可以使用类型Student的所有公开属性和方法。

所以,俺觉得约束这个词翻译的实在不好,叫约定多好。

10:减少使用自定义委托

FCL中的3个(或者说3系列)委托已经满足了大部分自定义委托的需求,所以基本上不再需要自定义委托了。

它们是:

Action表示接受0个或多个输入参数,执行一段代码,但是没有任何返回值;

Func表示接受0个或多个输入参数,执行一段代码,同时有返回值;

Predicate表示定义一组条件并判断参数是否符合条件;

 更多话题,期待下一期。

C#高效编程话题集3(每期10话题)

Creative Commons License本文基于 Creative Commons Attribution 2.5 China Mainland License发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名 http://www.cnblogs.com/luminji(包含链接)。如您有任何疑问或者授权方面的协商,请给我留言。
目录
相关文章
|
23天前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
23天前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
|
2月前
|
C#
24. C# 编程:用户设定敌人初始血值的实现
24. C# 编程:用户设定敌人初始血值的实现
23 0
|
23天前
|
存储 安全 网络安全
C#编程的安全性与加密技术
【4月更文挑战第21天】C#在.NET框架支持下,以其面向对象和高级特性成为安全软件开发的利器。本文探讨C#在安全加密领域的应用,包括使用System.Security.Cryptography库实现加密算法,利用SSL/TLS保障网络传输安全,进行身份验证,并强调编写安全代码的重要性。实际案例涵盖在线支付、企业应用和文件加密,展示了C#在应对安全挑战的同时,不断拓展其在该领域的潜力和未来前景。
|
23天前
|
人工智能 C# 开发者
C#编程中的图形界面设计
【4月更文挑战第21天】本文探讨了C#在GUI设计中的应用,介绍了Windows Forms、WPF和UWP等常用框架,强调了简洁界面、响应式设计和数据绑定等最佳实践。通过实际案例,展示了C#在企业应用、游戏开发和移动应用中的GUI实现。随着技术发展,C#在GUI设计的未来将趋向于跨平台、更丰富的组件和AI集成,为开发者创造更多可能性。
|
23天前
|
存储 算法 C#
C#编程与数据结构的结合
【4月更文挑战第21天】本文探讨了C#如何结合数据结构以构建高效软件,强调数据结构在C#中的重要性。C#作为面向对象的编程语言,提供内置数据结构如List、Array和Dictionary,同时也支持自定义数据结构。文章列举了C#实现数组、链表、栈、队列等基础数据结构的示例,并讨论了它们在排序、图算法和数据库访问等场景的应用。掌握C#数据结构有助于编写高性能、可维护的代码。
|
23天前
|
开发框架 Linux C#
C#编程的跨平台应用
【4月更文挑战第21天】C#与.NET Core的结合使得跨平台应用开发变得高效便捷,提供统一编程模型和高性能。丰富的类库、活跃的社区支持及Visual Studio Code、Xamarin等工具强化了其优势。广泛应用在企业系统、云服务和游戏开发中,虽面临挑战,但随着技术进步,C#在跨平台开发领域的前景广阔。
|
23天前
|
人工智能 C# 云计算
C#编程的未来发展趋向
【4月更文挑战第21天】C#编程未来将深化跨平台支持,强化云计算与容器技术集成,如.NET Core、Docker。在AI和ML领域,C#将提供更丰富框架,与AI芯片集成。语言和工具将持续创新,优化异步编程,如Task、async和await,提升多核性能。开源生态的壮大将吸引更多开发者,共创更多机遇。
|
23天前
|
程序员 C#
C#编程中的面向对象编程思想
【4月更文挑战第21天】本文探讨了C#中的面向对象编程,包括类、对象、封装、继承和多态。类是对象的抽象,定义属性和行为;对象是类的实例。封装隐藏内部细节,只暴露必要接口。继承允许类复用和扩展属性与行为,而多态使不同类的对象能通过相同接口调用方法。C#通过访问修饰符实现封装,使用虚方法和抽象方法实现多态。理解并应用这些概念,能提升代码的清晰度和可扩展性,助你成为更好的C#程序员。
|
23天前
|
开发框架 安全 .NET
C#编程高手的成长之路
【4月更文挑战第21天】本文揭示了成为C#编程高手的路径:牢固掌握基础知识和面向对象编程,深入了解C#特性如泛型和委托,精通ASP.NET等框架工具,养成良好编程习惯,持续学习实践并参与开源项目,勇于挑战创新。通过这些步骤,不断提升编程技能,迈向C#编程的巅峰。