基于几天前在 SO 中提出的以下问题:GetType() and polymorphism 并阅读 Eric Lippert's 答案,我开始思考是否使 GetType()
不是虚拟的真的能确保一个对象不能对其 0x231348 撒谎。
具体来说,埃里克的回答说明如下:
现在的问题是:我可以制作一个在类型上撒谎的对象而不是立即显而易见的吗?我在这里可能大错特错,如果是这种情况,我很想澄清一下,但请考虑以下代码:
public interface IFoo
{
Type GetType();
}
以及上述接口(interface)的以下两个实现:
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();
}
果然
Type
输出错误的 badFoo
。现在我不知道根据 Eric 将这种行为描述为“极其危险的特征”,这是否有任何严重影响,但这种模式是否会构成可信的威胁?
最佳答案
好问题!在我看来,如果 GetType 在对象上是虚拟的,你只能误导其他开发人员,而事实并非如此。
您所做的类似于隐藏 GetType,如下所示:
public class BadFoo
{
public new Type GetType()
{
return typeof(int);
}
}
使用此类(并使用 the sample code from the MSDN for the GetType() method )您确实可以拥有:
int n1 = 12;
BadFoo foo = new BadFoo();
Console.WriteLine("n1 and n2 are the same type: {0}",
Object.ReferenceEquals(n1.GetType(), foo.GetType()));
// output:
// n1 and n2 are the same type: True
所以,哎呀,你已经成功撒谎了,对吧?
好吧,是也不是......考虑到使用它作为漏洞利用意味着使用您的 BadFoo 实例作为某个方法的参数,这可能是
object
或对象层次结构的公共(public)基类型。像这样的东西:public void CheckIfInt(object ob)
{
if(ob.GetType() == typeof(int))
{
Console.WriteLine("got an int! Initiate destruction of Universe!");
}
else
{
Console.WriteLine("not an int");
}
}
但是
CheckIfInt(foo)
打印“不是整数”。因此,基本上(回到您的示例),您实际上只能使用某人针对您的
IFoo
接口(interface)编写的代码来利用您的“谎言类型”,这非常明确地说明它具有“自定义” GetType()
方法这一事实。只有当 GetType() 在对象上是虚拟的,您才能制作一个“谎言”类型,该类型可以与上面的
CheckIfInt
之类的方法一起使用,以在其他人编写的库中造成严重破坏。关于c# - GetType() 会撒谎吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16787719/