2013-10-29 60 views
1

爲什麼重新清晰想讓我不要隱藏抽象類中的屬性? 它希望我使用'新',但是總是可取的? 這似乎意味着隱藏一個變量,所以用戶不能做base.property是一件壞事。爲什麼resharper更喜歡不隱藏另一個抽象類中抽象類的屬性?

我只是有點困惑這個概念OO,想知道是否有支持或反對它強有力的理由。

public abstract class baseClass{ 
protected string commonProperty {get; set;} 
} 

public abstract class moreSpecificBaseClass : baseClass { 
    // Resharper would prefer I use 'new' below 
    protected string commonProperty = "Some specific setting"; 
} 

public class verySpecificClass : moreSpecificBaseClass { 
// Some code 
} 

回答

5

MSDN documentation

雖然你可以隱藏的成員,而無需使用new修飾符,該 結果是一個警告。如果使用新的顯式隱藏成員,它 抑制此警告並記錄事實得出 版本的目的是作爲替代。

隱藏類成員可能會導致誤解和微妙的錯誤。因此,編譯器會警告您,並要求您通過使用「新」修飾符來使您意圖隱藏可能有害的成員。這可以防止意外隱藏基礎類型成員而不被忽視。

隱藏成員時,就會發現問題是如何潛入你的代碼這個小例子:

public abstract class A 
    { 
     public int Value = 0; 
    } 

    public class B : A 
    { 
     // This hides the Value member from the base type A 
     public new int Value = 0; 
    } 

    static void SetValue(B obj, int value) 
    { 
     obj.Value = value; 
    } 

    static void AddToValue(A obj, int value) 
    { 
     obj.Value += value; 
    } 

    static void Main(string[] args) 
    { 
     B obj = new B(); 

     SetValue(obj, 11); 
     AddToValue(obj, 5); 

     Console.Out.WriteLine("obj.Value = " + obj.Value); 
     Console.Out.WriteLine("((A) obj).Value = " + ((A) obj).Value); 
     Console.Out.WriteLine("((B) obj).Value = " + ((B) obj).Value); 
    } 

這將輸出:

obj.Value = 11 
((A) obj).Value = 5 
((B) obj).Value = 11 

只要看一眼的主要方法的流程,你可能會認爲在該方法結束時,obj.Value的值是16(= 11 + 5)。但它不是 - 這是更糟糕:這取決於你如何訪問價值成員,你會遇到不同的值。

現在,在這個小例子,爲什麼輸出是不一樣的,而不是在所有情況下的預期值可能是容易和快速地被發現的原因(一個或多個)。但是想象一下大型軟件項目,許多類,大量繼承的,方法參數是抽象基類或接口類型,第三方類庫,你的名字......,而造成隱藏成員的問題可能會變得更加困難鑑別。

2

如果您不希望外界能夠訪問base.property,應該受到保護。如果是這樣,你不應該在派生類中重新定義它。如果根本不應該派生類可用,請將其設爲私有。

它表明新的防止歧義,但在現實中,你不應該在那裏開始。

的原因是,如果我這樣做:

var item = new verySpecificClass(); 
var val = item.commonProperty; 

var basic = (baseClass)item; 
if(val == basic.commonProperty) 

我會得到比一個合理的程序員所期望的不同的結果。