程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> [ C# ] 判斷一個類是否實現了某個接口的多種方法及性能分析,

[ C# ] 判斷一個類是否實現了某個接口的多種方法及性能分析,

編輯:C#入門知識

[ C# ] 判斷一個類是否實現了某個接口的多種方法及性能分析,


IEntity為一個接口,Entity為實現IEntity接口的類:

interface IEntity
{
    int Id { get; set; }
}

public class Entity : IEntity
{
    public int Id { get; set; }
    public string Prop { get; set; }
}

我們要判斷Entity是否實現了IEntity接口,根據找到的帖子

c# 如何判斷一個類是否實現了某個接口

在C#中判斷某個類是否實現了某個接口

整理有如下五種方式:

1. 

Entity entity = new Entity();
if (entity is IEntity)
{
}

2.

Entity entity = new Entity();
IEntity temp = entity as IEntity;
if (temp != null)
{
}

3.

if (typeof(IEntity).IsAssignableFrom(typeof(Entity)))
{
}

4.

if (typeof(Entity).GetInterfaces().Contains(typeof(IEntity)))
{
}

5.

 if (typeof(Entity).GetInterface("IEntity")!=null)
 {
 }

但是我們知道,前2種方式要實例化Entity的新實例,後面三種方式要用到反射,這都是相對耗性能的操作!

那麼這幾種判斷Entity是否實現了IEntity接口的方式哪一種相對來說對性能的消耗低呢?

我們讓每個方法都執行1000萬次:(以下測試均為Release 模式,.net framework 4.5.1框架)

Stopwatch stopwatch = null;
int count = 10000000;
Console.WriteLine("執行次數 {0}", count);

stopwatch = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
    Entity entity = new Entity();
    if (entity is IEntity) { }
}
Console.WriteLine(stopwatch.Elapsed);

stopwatch = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
    Entity entity = new Entity();
    IEntity temp = entity as IEntity;
    if (temp != null) { }
}
Console.WriteLine(stopwatch.Elapsed);

stopwatch = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
    if (typeof(IEntity).IsAssignableFrom(typeof(Entity))) { }
}
Console.WriteLine(stopwatch.Elapsed);

stopwatch = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
    if (typeof(Entity).GetInterfaces().Contains(typeof(IEntity))) { }
}
Console.WriteLine(stopwatch.Elapsed);

stopwatch = Stopwatch.StartNew();
for (int i = 0; i < count; i++)
{
    if (typeof(Entity).GetInterface("IEntity")!=null) { }
}
Console.WriteLine(stopwatch.Elapsed);

  測試結果:

   執行1億次的測試如下:

可以看出使用了反射的後三種方式的性能消耗明顯高於前兩種方式。那麼是不是結果一定是這樣呢?

我們回到上面Entity類的定義發現,Entity類只有2個屬性,而實例化Entity的主要開銷是是根據類型所有字段的長度總和計算的。那麼我們把Enity的屬性增加到30個,每個方法執行1億次的結果:

這時發現使用了反射的後三種方式的性能消耗幾乎沒有變化,而有實例化操作的前兩種方式所消耗的時間發生了成倍的增長!

我們繼續增加Enity的屬性到60個,每個方法執行1億次的結果:

繼續增加Enity的屬性到90個,每個方法執行1億次的結果:

當Entity類的屬性到90的時候,實例化所需要的性能消耗已經遠遠超過兩次typeof()所帶來的性能消耗了。

最後我的結論是,在類和接口的屬性/字段數量少的時候,判斷某個類是否實現了某個接口,性能消耗依次是:方式2<方式1<方式3<方式4<方式5

        在類和接口的屬性/字段相對較多的時候,判斷某個類是否實現了某個接口,性能消耗依次是:方式3<方式2<方式1<方式4<方式5

那麼為什麼方式2的性能要優於方式1,就留給園友們來回答吧    demo下載

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved