2011-07-26 23 views
17

在@this question中,評論者@Jon Egerton提到MyClassVB.Net中的關鍵字。從來沒有使用過它,我去了,發現它的documentationC#中的MyClass相同

的MyClass的關鍵字的行爲就像一個對象變量指向一個類的當前實例最初實施。 MyClass與Me類似,但對它的所有方法調用都被視爲方法爲NotOverridable。

我可以看到,在某些特定情況下,這可能會有用。我想不出的是,你將如何在C#中獲得相同的行爲 - 也就是確保實際調用虛擬方法myMethod對當前類中的myMethod,而不是派生的myMethod(又名in IL,調用call而不是callvirt)?

雖然我可能只是有一個完整的心理空白時刻。

+0

當然,你可以用反射做到這一點,'DynamicMethod'和定製IL-代(使用'call'而不是'callvirt'你的建議),但你最終用了很多醜陋代碼的東西可能是一個壞主意。如果你出於某種原因真的需要這種行爲,那麼Heinzi的解決方法就是要走的路。 – LukeH

回答

14

According to Jon Skeet,有沒有這樣的等價物:

沒有,C#沒有VB.NET的MyClass的關鍵字的等效。如果你想保證不要調用一個方法的重寫版本,你需要首先使它成爲非虛擬的。

一個顯而易見的解決辦法是這樣的:

public virtual void MyMethod() 
{ 
    MyLocalMethod(); 
} 

private void MyLocalMethod() 
{ 
    ... 
} 

然後,你可以調用MyLocalMethod()當VB用戶會寫MyClass.MyMethod()

+0

如果你正在實現一個基類,這看起來很好,如果你繼承和繼承,那就不那麼好了。 –

+0

@Damien:對。幸運的是,解決這個限制並不難(請參閱我的編輯)。 – Heinzi

3

在VB.Net中沒有C#等價於MyClass關鍵字。要保證不會調用某個方法的重寫版本,只需將其設爲非虛擬。

+0

如果你想讓它被覆蓋?或者你是否說這是不可能的? –

+0

@George Duckett就我所能想到的而言是不可能的。 – Numenor

1

除了說它不存在的答案,所以你必須使它非虛擬。

這是一個​​(閱讀:不要這樣做!)變通辦法。但嚴重的是,重新考慮你的設計。

基本上移動的任何方法必須有一個叫做'super'-base class,它位於你現有的基類之上。在你現有的類中調用base.Method()總是調用未覆蓋的類。

void Main() 
{ 
    DerivedClass Instance = new DerivedClass(); 

    Instance.MethodCaller(); 
} 


class InternalBaseClass 
{ 
    public InternalBaseClass() 
    { 

    } 

    public virtual void Method() 
    { 
     Console.WriteLine("BASE METHOD"); 
    } 
} 

class BaseClass : InternalBaseClass 
{ 
    public BaseClass() 
    { 

    } 

    public void MethodCaller() 
    { 
     base.Method(); 
    } 
} 

class DerivedClass : BaseClass 
{ 
    public DerivedClass() 
    { 

    } 

    public override void Method() 
    { 
     Console.WriteLine("DERIVED METHOD"); 
    } 
}