2011-07-14 78 views

回答

1

你可以在你的方法中使用「new」關鍵字來「隱藏」一個未被聲明爲抽象/虛擬的方法,但是如果方法是從變量類型 - 作爲基類轉換,它不會調用您的新方法。這與重寫相似。

例子:

public class A 
{ 
    public string GetName() { return "A"; } 
} 

public class B : A 
{ 
    // this method overrides the original 
    public new string GetName() { return "B"; } 
} 

擴展方法允許你添加新的方法,以任何類,即使你沒有自己的源代碼或他們是密封的。這是不一樣的壓倒一切的

public sealed class A // this could even be from a dll that you don't have source code to 
{ 
} 
public static class AExtensionMethods 
{ 
    // when AdditionalMethod gets called, it's as if it's from inside the class, and it    
    // has a reference to the object it was called from. However, you can't access 
    // private/protected fields. 
    public static string AdditionalMethod(this A instance) 
    { 
     return "asdf"; 
    } 
} 

另一種選擇是使用接口,讓您可以有兩個具有相同的方法,兩種完全不同的對象,而是從一個變量調用時型鑄造作爲接口,它看起來類似於重寫。

您也可以使用像Microsoft Moles或CastleWindsor這樣的Proxy Mocking框架的形式 - >它們有一種實例化具有與真實對象相同接口的「代理」對象的方法,但可以提供一種不同的實現方式每種方法。

+1

這不會「覆蓋」任何東西。它只是隱藏了基本類型的底層方法。不同之處在於,當您調用基本方法時,CLR不會調用您的「overriden」方法,因爲它不在繼承鏈中。因此,正確的答案是,您無法重寫非虛擬/抽象方法,但可以隱藏它。 –

+0

你說得對,我改變了措辭以更好地解釋它。 –

1

不,沒有其他辦法。如果基本方法未標記爲virtual,您可以隱藏 現有方法,但它不具有相同的效果(沒有多態性 - 調用將根據變量類型調度,而不是實際對象類型)。

1

擴展在這種情況下不起作用。對象擁有屬性和方法優先。但是,您可以使用擴展來重載方法。

您可以通過使擴展更靠近您要使用它的位置的命名空間來覆蓋擴展中定義的方法。

例子:

namespace ConsoleApplication2 

{ 

    using System; 

    using ConsoleApplication3; 

    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      ThirdPartyClass t = new ThirdPartyClass(); 
      Console.WriteLine(t.Fun("hh")); 
      Console.WriteLine(t.Fun(1)); 
     } 
    } 


    public static class LocalExtension 
    { 
     public static string Fun(this ThirdPartyClass test, int val) 
     { 
      return "Local" + val; 
     } 

     public static string Fun(this ThirdPartyClass test, string val) 
     { 
      return "Local" + val; 
     } 
    } 
} 


namespace ConsoleApplication3 

{ 

    public class ThirdPartyClass 
    { 
     public virtual string Fun(string val) 
     { 
      return "ThirdParty" + val.ToUpper(); 
     } 
    } 


    public static class ThripartyExtension 
    { 
     public static string Fun(this ThirdPartyClass test, int val) 
     { 
      return "ThirdParty" + val; 
     } 
    } 
}