[英]Get Default Equality Comparer from Variable Type?
有沒有辦法獲得給定類型的默認比較器,其中類型是可變的並且僅在運行時知道? 考慮以下:
var RT = typeof(string);
var comparer = EqualityComparer<RT>.Default;
這顯然不能編譯,但如果編譯了,則comparer
的值應該等於EqualityComparer<string>.Default
我能想到的唯一方法是制作一個可以通過反射調用的“盒裝”比較器(見下文)。 這行得通,但它很麻煩。 有沒有更好的方法來做到這一點?
澄清一下,由於反射,這不是一個好主意,但為什么我需要它?
有問題的算法是大型遺留搜索 API 的一部分。 消費者將對象列表(例如List<Person>
)傳遞給 API 內部創建類型特定的索引(使用反射),以便調用者可以搜索 object 中的任何字段(例如,可能是姓氏)。 這通常不是必需的,但在我正在服務的用例中,我們正在搜索非常大的集合與其他非常大的集合。 為此目的,數據庫存儲過程可能更好。 但是現在我需要修補這個遺留的 API 以支持用戶定義的比較算法,並且還支持用戶選擇不提供任何比較算法的情況,我只知道運行時類型RT
。
// Example usage
// Assume "RT" is a Type known only at runtime (e.g., typeof(string))
var box = typeof(BoxedComparer<>);
var generic = box.MakeGenericType(RT);
var specific = (IBoxedComparer) Activator.CreateInstance(generic);
// Now with specific you can get the equality comparer for the runtime type (RT)
var comparer = specific.GetEqualityComparer();
public interface IBoxedComparer
{
// You need the interface to allow a "typeless" cast
EqualityComparer GetEqualityComparer()
}
public BoxedComparer<T> : IBoxedComparer
{
public EqualityComparer GetEqualityComparer() { return EqualityComparer<T>.Default; }
}
反射不是執行此操作的推薦方法。 可能重構是有序的。 例如,如果var comparer
以這種方式通過反射創建后,將如何實際使用它並不清楚。
為了減輕性能問題,您可以在創建比較器時緩存它們,就像EqualityComparer<T>
的源在內部為每個T
所做的那樣。 但是這樣你的代碼就會變得更加混亂。
那就是說...
var comparer = typeof(EqualityComparer<>).MakeGenericType(RT).GetProperty("Default", BindingFlags.Public | BindingFlags.Static).GetValue(null);
其中RT
是我們在編譯時不知道的運行時Type
實例。
要求:
using System.Collections.Generic;
using System.Reflection;
請注意,當通過反射訪問static字段或屬性時, null
傳遞給 GetValue/SetValue(通常您傳遞包含該屬性的 object)。
同樣,此代碼不是推薦的方法。 可讀性、可重用性、維護和錯誤處理選項並未真正考慮。 這個例子只是展示了一種更簡單的方法來獲得所需的東西,而無需引入額外的類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.