有这样一个类:
class T
{
protected string aaa;
public T(string val)
{
aaa = val;
}
public string GetString(T t)
{
return t.aaa;
}
}
和以下两种用法:
1):
T t1 = new T("test");
Console.WriteLine(t1.GetString(t1));
2):
T t1 = new T("test1");
T t2 = new T("test2");
Console.WriteLine(t1.GetString(t2));
请选择答案并说明理由:
a) 编译不通过
b)第一种用法不能通过
c)第二种用法不能通过
d)都能通过
附注:首先最好别先编译测试结果,只凭感觉做答案
打印 | 张贴于 2004-06-23 11:01:00 | Tag:暂无标签

留言反馈
想起中介,中介机构为了保护自己的利益,不允许交易双方直接约见,但双方可以通过中介来对话,呵呵....
对于GetString访问另一个类型的protect成员,因为protect限制的不是实例间的访问,而是类,只要访问者与被访问者的类型,符合相同或访问类型继承自被访问类型即可.
等下写个看看
要想访问Control内部的protected成员Context,你的MyControl必须是Control的派生类才行啊。很奇怪,既然要写自己的Control,为什么不从Control派生呢?:)
@minbear:
是啊,有日子没动笔啦!一来是工作繁忙,抽不出整块的时间写点儿东西;二来也没有想好写些什么。还好还有些存货,我整理一下尽早与大家分享吧!:)
public class MyControl
{
public HttpContext GetContext(Control that)
{
return that.Context;
}
}
..
其实在例如 Equals 这样的方法中,直接访问另外一个对象的同一个类的成员是很经常的.
这跟内联、IL都没什么关系,原理上讲,private/protected/internal等等成员访问级别的概念都是在编译器一级实现的语言逻辑(或称功能),在运行期是没有什么显式的机制来保障的(比如说透过Reflection一样可以访问对象内部的private/protected的成员一样)。
另外,Lostinet所称不能取得Control类的Context的问题,是因为需要取得Context的那个类型并不是Control或其派生类,自然对于Control类型内部的成员而言是external的了,因而其Context对你就理所应当是protected了,那你当然就访问不到了。
这是个考面向对象基本概念的好问题。:)
在这个例子里面,甚至把protected改成private都一样能够通过。在T的内部处理T类型的东西,无论是this还是“that”,都可以毫无保留的访问到。
因为这是基于这么一个假设的:设计T这个类型的人,如果想要处理另外一个也是T类型的对象,一定知道自己正在干什么。因此怎么处理类型为T的这个对象就应该是设计这个类型T的作者的自由。
这个例子可以引申到另外一个例子:如果我从T派生出X,那会怎么样?如果T派生X但是aaa是private的,那又会怎么样?
前者无论如何都可以通过,后者则无法通过。
Agree with tanzhaoqing
这里还想问问这样一个问题。不知道各位怎么看的。
-- 我这里保留了来自某位网友的这样一个提问,就是问这样做合理不合理。
-- 网友的名字应该是Shun,可惜我忘记是在哪里看到的了。:<对不起。
这个自动类型转换应不应该?
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
}
}
}
我感觉这里编译器处理的不好,不应该自动进行类型转换,应该报错无权访问。
如果自动转换,很容易造成混乱。
---引用结束
我也觉得这样的做法很有问题。不合理。可是当时刘敏和袁伟都说合理。
关键在于这句
public int GetM(Parent p){return p.m;}//查看返回的m是父类还是基类
如果带入的是Base的话,我可以理解,但是带入的是Parent的。这个时候因为在Base内,自动的把Parent替换为Base,从而可以自由的对Base的私有成员访问。
两种方法都可以
都可以通过,而且运行结果也应该没问题
protected string aaa
aaa虽然是protected的但是在类成员函数是可以使用它的
Console.WriteLine(t1.(t2));
这条语句应该输出:test2
成员函数只和类有关,对于同一个类的不同实例函数都是一样的
不能通过的是在
public string GetString(T t)
{
return t.aaa;
}
而不是传什么进去。
我就尝试过用类似的方法想取某个Control的Context,结果不允许这样访问。
第二种不能通过
protected string aaa;是受保护的,return t.aaa只接受自身类或者继承类调用