是否有可能超載默認函數運算符(()運算符)在C#?如果是這樣 - 如何?
在C#中,只有方法和委託才能作爲函數調用。在C#中,代表儘可能接近您所問的C++ function objects。
如果沒有,是否有解決方法來創建類似的影響?
你不能得到你想要的,但你可以隱約地關閉(語法)。
使用重載的轉換操作符
定義:
public static implicit operator DelegateType(TypeToConvert value)
{
return value.TheMethodToCall;
}
用法:
var someValue = new TypeToConvert();
DelegateType someValueFunc = someValue;
someValueFunc(value1);
這得到你想要的最終語法,但需要你做一箇中間轉換,你指定類型。
你可以這樣做:
- 你的價值分配到一個局部變量,或者將它傳遞給函數取匹配委託類型(隱式轉換)
- 鑄造它(顯式轉換)
使用索引
定義:
public DelegateType this[ParameterType1 value1, ...]
{
get
{
// DelegateType would take no parameters, but might return a value
return() => TheMethodToCall(value1);
}
}
用法:
variable[value1]();
索引器版本有古怪的語法,但這樣做在你原來的問題的例子(WRT標準C#成語)。它也是有限的,因爲你不能定義一個採用零參數的索引器。
如果你想要一個無參數函數的解決方法是製作一個虛擬參數(可能是object
)並向它傳遞一個丟棄值(可能是null
)。但是這個解決方案真的很糟糕,並且需要你仔細研究以瞭解使用情況。如果你想要一個重載你的虛擬類型的單個參數,它也會中斷。
的動機是使一個類或實例表現得像一個函數,使一個方便的登錄界面
有了這個動機在腦海,我可能會建議你放棄上述這些選項。對於這個問題他們是矯枉過正的。如果你擴大你允許的解決方案,你可能會發現你更喜歡其中一個。
使用動態而不是
我提到的其他方法需要強類型,並且絕不普通。這可能是你描述的一個巨大的缺點。
如果你想要較弱的綁定,你可以看看Dynamic
。這將要求您調用命名方法,並且不會允許您嘗試實現的簡短語法。但它會鬆散地束縛,並可能失敗。
使用更簡單。網功能代替
還有其他的解決方案,你可以看看。
接口:
創建基礎ILoggable
接口,具有標準化的方法。
擴展方法:
與.Log()
extension methods創建日誌接口。擴展方法可以是通用的,並且可以採用基本類型,如object
,因此您不必修改現有的類就可以支持此類。
覆蓋ToString
:
記錄意味着你正在嘗試將數據轉換成文本(因此它可以記錄)。考慮到這一點,您可以簡單地覆蓋ToString
方法。
您可以在所有這些情況下創建方法重載,但它們將強烈綁定到每種類型。但是,您在原始問題中所要求的解決方案也強烈地依賴於該類型,因此這些解決方案並不是真的處於劣勢。
現有的解決方案
我見過的現有的.NET日誌庫靠你重寫ToString
操作。正如我上面所說,這是有道理的,因爲你的日誌是文本的。
有關的.Net記錄以前的藝術,看到這些庫:
注意有關內置委託類型
確保在所有這些情況下使用built-in delegate types,而不是定義自己的委託類型。最終會減少混淆,並要求您編寫更少的代碼。
// function that returns void
Action a1 = ...;
Action<TParameter1> a2 = ...;
Action<TParameter1, TParameter2> a3 = ...;
// etc
// function that returns a value
Func<TReturn> f1 = ...;
Func<TParameter1, TReturn> f2 = ...;
Func<TParameter1, TParameter2, TReturn> f3 = ...;
// etc
該操作符將如何使用?你能發表一個使用'A'類型的實例的代碼示例嗎? – 2010-03-15 20:25:14
當涉及到C++ – 2010-03-15 20:44:24
@Isak時,請不要混淆「可行」與「合理」,我不認爲我是。 – 2010-03-15 21:41:10