有被許多GUI框架,以確保事情真的很酷的圖案編碼是否正確無誤:重載通用擴展方法與約束 - 的Func鍵模式
interface IBase1 {}
interface IBase2 {}
class Base1 : IBase1
{
public int x { get; set; }
}
class Base2 : IBase2
{
public int y { get; set; }
}
static class Helpers
{
public static void ToProp<T,Y> (this T obj, Func<T, Y> getter)
{
}
}
class Program
{
static void Main(string[] args)
{
var b1 = new Base1();
var b2 = new Base2();
b1.ToProp(b => b.x);
b2.ToProp(b => b.y);
}
}
這裏的美妙的事情是,當你鍵入b => b.x
,視覺Studio會給你IntelliSense,如果你試圖訪問一個不正確的屬性,編譯器會報錯。我經常在MVVM框架中看到這種情況。他們通常會將b => b.x
作爲表達式樹並解析出參數的名稱,以便正確地引發通知屬性更改消息。
我想延長這一點,並用下面的取代ToProp定義,基本上具有取決於基本接口上的兩個代碼路徑:
static class Helpers
{
public static void ToProp<T,Y> (this T obj, Func<T, Y> getter)
where T : IBase1
{
// Do something custom for 1
}
public static void ToProp<T, Y>(this T obj, Func<T, Y> getter)
where T : IBase2
{
// Do something custom for 2
}
}
這將不會編譯原樣 - 兩個ToProp
調用都會因模糊的方法解析錯誤而失敗。這是一個衆所周知的SO問題 - 對象約束不是方法解析過程的一部分(例如參見Lipert的blog)。
但我不禁想知道是否沒有辦法。例如,我嘗試用this Base1 obj
代替this T obj
,但是在這種情況下,您將失去對財產分辨率的支持,也可以編寫b1.ToProp(b => b.y)
。我想,這可能會遇到運行時異常。我也嘗試了隱式轉換 - 但不幸的是,這不是方法解析過程的一部分。
這是因爲我擴展了ReactiveUI框架以使用Caliburn.Micro。 ReactiveUI有這個非常好的擴展方法ToProperty,它需要一個ReactiveUI ViewModel。稍作修改後,我可以修改該代碼以使用Caliburn.Micro視圖模型。但是,然後我遇到了上述模糊的方法問題。在此期間,我只是致電Caliburn.Micro方法ToPropertyCM
。
任何人都知道我應該追求這樣的工作的聰明大道?並且可擴展到新的基類類型?
編輯修正了一個例子,表明它是一個我感興趣的簡單接口。順便說一句,我試過包裝方法b.c.如果我理解方法解析,它應該允許您對解析過程中的模板參數的類型進行約束檢查。但是,正如我所提到的,隱式類型轉換在解析過程中不起作用。
正如你在文中提到它,你真的只是想提取表達的財產? – poke
是的,這就是我如何得到屬性名稱...只是解析表達式樹(大多數實現目前有一個相當有限的解析能力)。 – Gordon