昨天在我的随笔My god!!属性可以变成方法!!中提到,一个类继承一个类的属性,然后可以使用new方法使用一个方法覆盖掉此属性,这让我觉得诧异。在回复中有部分人是这样理解这种现象的,属性在中间语言时也被翻译成了方法。

我重新写了一个类

public class ClassA
{
    
private string a="ClassA A";
    
//属性
    public string A
    
{
        
get
        
{
            
return a;
        }

        
set
        
{
            a
=value;
        }

    }


    
//字段
    public string B="ClassA B";

    
//方法
    public string C()
    
{
        
return "ClassA C";
    }


    
//重载的方法
    public string D()
    
{
        
return "ClassA D";
    }


    
public string D(string arr)
    
{
        
return "Hello"+arr;
    }

}


我们用ildasm打开生成的文件,

的确A的属性访问器被编译成了Set_A和Get_A方法。似乎我们已经找到了此问题的答案。

但是请你看下面的代码,事实将推翻此理论

public class ClassB:ClassA
{
    
//A是一个属性,我用方法隐藏它
    new public string A()
    
{
        
return "ClassB A";
    }


    
//B是一个字段,我用方法隐藏它
    new public string B()
    
{
        
return "ClassB B";
    }


    
//C是一个方法,我用字段隐藏它
    new public string C="ClassB C";

    
//D是一个重载了的方法,我用一个字段隐藏它
    new public string D="ClassB D";
}

你觉得这样的代码编译能通过吗,或者编译会出现警告吗??答案却是这段代码编译通过而且没有任何错误提示。


结论:属性和字段和方法(不管返回值),可以使用任何同名的属性或字段或方法隐藏。带参数的方法可以用参数签名相同的方法隐藏。一批重载的方法只需要一个字段或属性可全部隐藏。

PS:如果把类B中的成员换成private或protected则覆盖不能起到效果,访问时需访问父类成员。

最后:感觉使用new关键字进行隐藏的时候情况十分复杂,建议采用同类型成员进行隐藏,属性隐藏属性,方法隐藏方法,以免给编程带来不必要的麻烦。