【发布时间】:2013-05-23 04:02:55
【问题描述】:
基于几天前在 SO 中提出的以下问题:GetType() and polymorphism 并阅读了Eric Lippert's 的答案,我开始思考是否让GetType() 不是虚拟的真的可以确保一个对象不会对它的Type 撒谎.
具体来说,Eric 的回答如下:
框架设计者不会添加一个极其危险的功能,例如允许对象谎报其类型,只是为了使其与同一类型的其他三个方法保持一致。
现在的问题是:我能否制作一个 确实 谎报其类型的对象,而不会立即显而易见?我在这里可能大错特错,如果是这种情况,我很乐意澄清,但请考虑以下代码:
public interface IFoo
{
Type GetType();
}
以及上述接口的以下两种实现:
public class BadFoo : IFoo
{
Type IFoo.GetType()
{
return typeof(int);
}
}
public class NiceFoo : IFoo
{
}
那么如果你运行下面这个简单的程序:
static void Main(string[] args)
{
IFoo badFoo = new BadFoo();
IFoo niceFoo = new NiceFoo();
Console.WriteLine("BadFoo says he's a '{0}'", badFoo.GetType().ToString());
Console.WriteLine("NiceFoo says he's a '{0}'", niceFoo.GetType().ToString());
Console.ReadLine();
}
果然badFoo输出了错误的Type。
现在我不知道这是否有任何严重影响,基于 Eric 将这种行为描述为“非常危险的功能”,但这种模式会构成可信的威胁吗?
【问题讨论】:
-
有趣的标题和主题!
-
IFoo.GetType和object.GetType不是一回事,所以除了风格不佳之外,这里没有发生任何不好的事情。编辑:通常GetType将在编译时未知的某些对象上调用,在大多数情况下object而不是一些狡猾的接口。 :) -
你的头衔先生,让我开心。
-
您只需介绍 新 成员,也称为
GetType,具有相同的签名。这与重要的GetType方法无关。您还可以使用new修饰符关键字创建一个隐藏相关GetType方法的公共实例方法。注意,如果你有一个像static Type Test<T>(T t) { return t.GetType(); }这样的通用方法(对T没有约束),那么像Test<IFoo>(new BadFoo())这样的东西仍然会调用原来的GetType方法。 -
@Jamiec - 问题“这种模式会构成可信的威胁吗?”不是修辞。