![](/img/trans.png)
[英]Type.GetType() and Assembly.GetType() returns different results
[英]Dynamic type resolution - multiple calls to Type.GetType or scanning all types in assembly?
我目前正在實施類型名稱解析方案。 可用信息與常規C#源項目中的信息非常相似:
Assembly
引用列表 using
名稱空間的列表 在運行時,對於每個要解析的類型名稱,該名稱要么是完全限定的(使用名稱空間,但不使用程序集名稱),要么是一個簡單的名稱,該名稱應來自using
名稱空間之一。
為了找到與每個標識符匹配的Type
,我正在考慮以下兩種策略之一:
使用Assembly.Load
預先加載所有程序集。加載並掃描所有類型。 具有名稱空間前綴與using
名稱空間之一匹配的所有簡單名稱都將被預先緩存。 還創建一個字典,將程序集中的每個名稱空間限定類型名稱直接映射到其Type
。 在加載階段將相應地執行沖突解決。
不要預裝任何東西。 每當類型名稱到達時,請嘗試以下順序:
假設名稱完全合格; 依次連接每個引用的程序集名稱以創建程序集限定名稱,然后調用Type.GetType
來查看我們是否獲得有效的類型。
如果上述步驟沒有產生任何有效的類型,並且名稱沒有前綴,則假定它是一個簡單名稱; 重復上述步驟,但每次在簡單名稱前using
命名空間之一,以查看是否獲得有效的類型。
哪種方法更可取,優缺點是什么?
目前尚不清楚每次運行將需要以這種方式解析多少個類型,但我假設介於10到100之間。在任何時候都可以引用多個程序集,每個程序集可能包含數百種類型。
我很想知道這兩種策略的相對表現,並想知道有關解決此情況的現有最佳實踐。 除了性能之外,了解行為副作用的任何區別也將非常有幫助:例如,掃描Assembly
所有類型是否對加載的類型執行所有靜態構造函數? 我希望這種方法在從引用程序集運行任何代碼時都盡可能地懶惰。
在新的.NET Standard中,事實證明,通過使用新的System.Reflection.Metadata
命名空間,還有一種更好的方法。 用他們自己的話說:
“該軟件包提供了一個低級.NET(ECMA-335)元數據閱讀器。
它是為提高性能而設計的,是構建打算提供自己的對象模型的高級庫(例如編譯器)的理想選擇。”
這是一個小代碼段,用於列出給定程序集文件中所有類型定義的名稱和名稱空間:
using System;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace MetadataTest
{
class Program
{
static void Main(string[] args)
{
using (var stream = File.OpenRead(args[0]))
using (var peFile = new PEReader(stream))
{
var metadataReader = peFile.GetMetadataReader();
foreach (var type in metadataReader.TypeDefinitions)
{
var definition = metadataReader.GetTypeDefinition(type);
var name = metadataReader.GetString(definition.Name);
var ns = metadataReader.GetString(definition.Namespace);
Console.WriteLine(ns + "." + name);
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.