[英]Why can't Interface ReadOnly properties be overridden in VB.NET, when it is valid in C#.NET?
[英]Why can't VB.Net find an extension method on an interface?
我有一個具有擴展方法的C#庫,類似於:
public interface ISomething { ... }
public class SomethingA : ISomething { ... }
public class SomethingB : ISomething { ... }
public static class SomethingExtensions
{
public static int ExtensionMethod(this ISomething input, string extra)
{
}
}
如果從C#調用該擴展程序,則工作正常,但如果從外部VB.Net應用程序調用,則存在問題:
Dim something = Me.SomethingManager.GetSomething(key)
Dim result = something.ExtensionMethod("extra")
這樣可以編譯良好,但是在運行時引發異常:
找不到類型為“ SomethingB”的公共成員“ ExtensionMethod”。
如果將VB.Net更改為顯式地使其成為接口,那么它將起作用:
Dim something as ISomething = Me.SomethingManager.GetSomething(key)
Dim result = something.ExtensionMethod("extra")
為什么? 為什么擴展方法在接口上起作用,但不能在實現該接口的類上起作用? 如果使用子類,是否會有同樣的問題? VB.Net擴展方法的實現是否不完整?
我可以在C#庫中做任何事情來使VB.Net在沒有顯式接口的情況下工作嗎?
關閉選項推斷后,此代碼...
Dim something = Me.SomethingManager.GetSomething(key)
Dim result = something.ExtensionMethod("extra")
...是相同的...
Dim something As Object = Me.SomethingManager.GetSomething(key)
Dim result As Object = something.ExtensionMethod("extra")
由於something
屬於Object
類型,因此找不到擴展方法,因為它未在Object
類型上定義。
現在,如果將Option Infer On
設置為,則將獲得與C#的var
關鍵字相同的結果。 類型將被自動推斷。 請注意,這也可能破壞現有代碼,但是可以為特定文件啟用該代碼,例如Option Strict
。
最佳實踐是將“ Option Strict
Option Infer
和“ Option Infer
都設置為“開”。
如果它拋出異常而不是給出編譯時錯誤,則表明您已禁用Option Strict ...我不知道那種情況下擴展方法會發生什么,因為它們通常是在編譯時解決的,但是關閉Option Strict后,綁定將繼續進行。
我建議您打開Option Strict,一切都應該很好。
(根據Richard的回答,您還需要導入名稱空間,但我假設您已經完成了該操作。如果您在嚴格啟用選項后忘記這樣做,則會看到編譯時錯誤。 )
為喬恩(Jon)指出正確的方向而歡呼,但是這里有足夠的需要一個完整的答案。
擴展方法是一個編譯器技巧,因此(在C#中):
var something = this.SomethingManager.GetSomething(key);
var result = something.ExtensionMethod("extra");
在編譯時轉換為:
ISomething something = this.SomethingManager.GetSomething(key);
int result = SomethingExtensions.ExtensionMethod(something, "extra");
作為類方法出現的靜態擴展方法僅僅是編譯器的靈巧性。
問題在於,VB中的Dim
與C#中的var
。 感謝VB的后期綁定,它更接近dynamic
。
因此,使用VB中的原始示例:
Dim something = Me.SomethingManager.GetSomething(key)
Dim result = something.ExtensionMethod("extra")
與C#不同,在VB中,要弄清楚something
類型直到運行時,並且不會使擴展方法起作用的編譯器聰明。 如果明確聲明了類型,則可以解析擴展方法,但是如果綁定得晚,則擴展方法將永遠無法工作。
如果他們使用Option Strict On
(如Jon所建議的那樣),那么它們將被迫始終聲明類型,發生早期綁定,並且編譯器的聰明才智使擴展方法起作用。 無論如何,這都是最佳實踐,但是由於他們沒有這樣做,這對他們來說是一個痛苦的改變。
這個故事的寓意:如果您希望VB的任何人靠近它,請不要在您的API中使用擴展方法:-S
您是否導入了包含定義該名稱空間的類的名稱空間。
例如。 如果沒有,您將看不到任何LINQ to Objects擴展方法
Imports System.Linq
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.