[英]Static type-checking of dynamic types not sharing an interface in C#
假設我有一些外部類,這些類具有按約定共享簽名的方法,但未實現接口:
class A {
public string getError();
}
class B {
public string getError();
}
如果我想創建一個接受兩種類型對象的實用函數,可以使用dynamic
:
void printError(dynamic obj) {
Console.WriteLine("Error: {0}", obj.getError());
}
但是,如果我傳遞了一些沒有getError
方法的類C
,那么這將是運行時錯誤。 鑒於我不能(直接)修改A
或B
,有沒有一種方法可以實現這一點,從而在沒有getError
方法的情況下傳遞類型將是編譯時錯誤,類似於我們在C ++模板中獲得的方法?
聽起來您有XY問題。 與其搞清楚如何使代碼的類型安全性降低,不如僅使用重載和重構?
public void PrintError(A obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
public void PrintError(B obj)
{
Console.WriteLine("Error: {0}", obj.getError());
//maybe some more logic
}
上面的代碼解決了您的問題,但是不再干燥。 這是我們重構的地方:
public void PrintError(A obj)
{
PrintError(obj.getError());
}
public void PrintError(B obj)
{
PrintError(obj.getError());
}
//This is private, so you can only call PrintError publicly with an A or B instance
private void PrintError(string error)
{
Console.WriteLine("Error: {0}", error);
//maybe some more logic
}
現在,您已經具有類型安全性,您無需重復自己,也不會通過與設計語言相反的方式來使用它來“對抗語言”。
當然,您可以定義多個原型,每個原型都接受一個不同的類。 編譯器將自動選擇匹配的方法簽名。 例:
public static void PrintError(ExternalClasses.A a)
{
Console.WriteLine(a.getError());
}
public static void PrintError(ExternalClasses.B b)
{
Console.WriteLine(b.getError());
}
另一種方法是定義自己的類並設置隱式轉換:
public class ErrorContainer
{
protected string _error = null;
public string getError()
{
return _error;
}
public override string ToString()
{
return getError();
}
static public implicit operator ErrorContainer(ExternalClasses.A a)
{
var e = new ErrorContainer();
e._error = a.getError();
return e;
}
static public implicit operator ErrorContainer(ExternalClasses.B b)
{
var e = new ErrorContainer();
e._error = b.getError();
return e;
}
}
然后,您可以定義PrintError接受ErrorContainer:
public static void PrintError(ErrorContainer e)
{
Console.WriteLine(e);
}
...可讓您“通過”以下任一類型:
var a = new ExternalClasses.A();
PrintError(a);
var b = new ExternalClasses.B();
PrintError(b);
在幕后,當然, A
和B
都將轉換為ErrorContainer
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.