这是不是C#的bug?(0分)

  • 主题发起人 主题发起人 LitterTiger
  • 开始时间 开始时间
L

LitterTiger

Unregistered / Unconfirmed
GUEST, unregistred user!
这个自动类型转换应不应该?
using System;
namespace ConsoleApplication3
{
class Base
{
private int m=2;
public int GetM(Parent p){return p.m;}//查看返回的m是父类还是基类的
}
class Parent:Base
{
private int m=3;
}
class test
{
public static void Main()
{
Base b=new Base();
Parent p=new Parent();
int r=b.GetM(p);
//事实证明返回的是基类的m
}
}
}
我感觉这里编译器处理的不好,不应该自动进行类型转换,应该报错无权访问。
如果自动转换,很容易造成混乱。
某人的看法:
这个在语义上确实容易让人混淆
但是代码确实是在base内部,访问私有变量也是理所当然,报错就牺牲了灵活性了
如果报错的话,base确实需要访问私有的m怎么办?
它也并没有违背大的原则
要是访问到了parent内部的m就不正确了
在定义parent类中的m的时候就应该想到这个m和base中的m完全没有一点关系
甚至如果你没有看到base的代码,你根本不知道你的m和父类中的m重复了
这时,如果父类访问到了子类中的m,是不是会造成麻烦?
一样的C#,可以写出让人摸不着头脑的代码,也可以写出十分清晰易懂的代码,避免混
乱的关键在于我们自己
下面是我的回复:
我想知道为什么把我上一个相同的回复删除?下面是又一个
我还是坚持原有的看法。
如你所说,我在parent类中加入m,甚至就不知道base里面也有m,无法顾忌到base,在
面向对象的思想中,也是不应该随便顾忌本对象之外的对象。
你似乎没有认识到我说的关键,我说的关键是隐式类型转换发起原因,在c++中,原因
只有一个,就是类型匹配,在这里它不是类型匹配,而是这样的:当一个父类想要进行
一个操作时,如果这个操作不存在或无法进行,它会自动试图访问子类的同名操作,也
是说它进行了隐式的类型转换。
这是不应该的,因为很容易看到,我写GetM的初衷是想访问parent里面的m,而不是
base里面的m。如果如此随便的进行隐式类型转换,然人感到我现在到底在对谁操作,
父类还是子类?
如你说说,为了灵活性,如果要访问base里面的东西,可以进行显式类型转换。

 
怎么没有讨论讨论?
 
我用DELPHI作了个差不多的试验,发现返回的parent里面的m,个人感觉还是C#不够严谨,这里不应进行隐式转换,因为传入的参数是Parent类,因此可以访问Parent类中的私有变量M。
 
/*public int GetM(Parent p){return p.m;}//查看返回的m是父类还是基类的*/
Parent类是派生于Base之后的类,还未派生你就引用了它,明显就错了.
我就不信---你不定义Parent类,Base还能用。
如下:
using System;
namespace ConsoleApplication3
{
class Base
{
private int m=2;
public int GetM(Parent p){return p.m;}//查看返回的m是父类还是基类的
}
class test
{
public static void Main()
{
Base b=new Base();
int r=b.GetM(XX);
//我不知道XX该填什么了?得问你了。也许还没编译就报错了。
}
}
}
 
楼上的朋友,你有一个明显的错误。C#的编译器并不同与一般的顺序编译器,它并不是顺序编译的。换句话说,C#编译器并不是建立在先声明再引用的基础上的。
 
私有变量可以在类之外访问吗?
 
呵呵,这正是问题所在呀
我上面的代码可是编译正常的哟
 
依我看:Base调用的是Parent类的方法.那么编译器就从Parent类的定义(方法,属性等)检查,一直追溯到Base类甚至到Object类!根据各类的方法、属性的可视性(public,private等定义),他会调用第一个被检查到的,有调用权限的类。
应该说Base类有权调用Base类的方法GetM()。这时它的程序的域就在Base里面(类似于变量的作用域概念)。而不在Parent里面。
所以这个问题与所谓的类型转换根本无关----从程序过程设计的角度来说的话。
我们来做个实验:
using System;
namespace ConsoleApplication3
{
class Base
{
public int m=2;
public int GetM(Last p){return p.m;}//查看返回的m是父类还是基类的
}
class Parent:Base
{
public int m=3;
}
class Last:Parent
{
private int m=4;
}
class test
{
public static void Main()
{
Base b=new Base();
Last l=new Last();
int r=b.GetM(l);
//事实证明返回的是Parent类的m
Console.WriteLine(r.ToString());
Console.Read();
}
}
}
Base类继承于Parent类,Last类继承于Parent类。
Base类调用Last类的方法。那么就从Last类追溯到Base类,而Last类已经继承了Base类的方法GetM(),而Base类没有权限调用Last类的m(在Last类的m是private的),但是到了Parent类时Base类就有权限调用m。
一楼写的程序说明编译器给了人们较多的、运用语法的空间。
 
一楼写的程序说明编译器给了人们较多的、运用语法的空间。如下:
using System;
namespace ConsoleApplication3
{
class test
{
public static void Main()
{
while(true){Console.WriteLine("GOOD!");}
}
}
}
//编译器可没兴趣给你报错
 
后退
顶部