簡體   English   中英

動態類型解析-多次調用Type.GetType還是掃描程序集中的所有類型?

[英]Dynamic type resolution - multiple calls to Type.GetType or scanning all types in assembly?

我目前正在實施類型名稱解析方案。 可用信息與常規C#源項目中的信息非常相似:

  • Assembly引用列表
  • using名稱空間的列表

在運行時,對於每個要解析的類型名稱,該名稱要么是完全限定的(使用名稱空間,但不使用程序集名稱),要么是一個簡單的名稱,該名稱應來自using名稱空間之一。

為了找到與每個標識符匹配的Type ,我正在考慮以下兩種策略之一:

  1. 使用Assembly.Load預先加載所有程序集。加載並掃描所有類型。 具有名稱空間前綴與using名稱空間之一匹配的所有簡單名稱都將被預先緩存。 還創建一個字典,將程序集中的每個名稱空間限定類型名稱直接映射到其Type 在加載階段將相應地執行沖突解決。

  2. 不要預裝任何東西。 每當類型名稱到達時,請嘗試以下順序:

    • 假設名稱完全合格; 依次連接每個引用的程序集名稱以創建程序集限定名稱,然后調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM