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下載