c# - GetType() 会撒谎吗?

标签 c# types

基于几天前在 SO 中提出的以下问题:GetType() and polymorphism和阅读 Eric Lippert's回答,我开始考虑如果让 GetType() 不是虚拟的真的确保一个对象不能谎报它的 Type

Eric 的回答具体如下:

The framework designers are not going to add an incredibly dangerous feature such as allowing an object to lie about its type merely to make it consistent with three other methods on the same type.

现在的问题是:我能否创建一个对象,使其确实在其类型上撒谎而不立即显而易见?我在这里可能大错特错,如果是这种情况,我很乐意澄清,但请考虑以下代码:

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();
}

果然 badFoo 输出了一个错误的 Type

现在我不知道这是否有任何严重的影响,因为埃里克将这种行为描述为“非常危险的特征”,但这种模式会构成可信的威胁吗?

最佳答案

好问题!在我看来,如果 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 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) 打印出“not an int”。

所以,基本上(回到你的例子),你真的只能利用某人针对你的 IFoo 接口(interface)编写的代码来利用你的“说谎类型”,这非常明确地表明它有“自定义”GetType() 方法。

只有当 GetType() 在对象上是虚拟的时,您才能够制作一个“谎言”类型,该类型可以与上面的 CheckIfInt 等方法一起使用,以在其他人编写的库中造成破坏。

关于c# - GetType() 会撒谎吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16787719/

相关文章:

Python:对多个字典使用相同的键TypeError: 'str'对象不支持项目分配

python - 如何在 Python 中将指针指定为函数的参数?

c# - Entity Framework 核心 : What is the fastest way to check if a generic entity is already in the dbset and then add or update it?

c# - 循环遍历 ListView 选中的项目

mysql - 在 MySQL 上创建类型

python - NumPy 数据类型比较

c# - 无法加载类型 'System.IdentityModel.Tokens.JwtSecurityToken'

具有透明区域的 C# PNG 图像作为按钮

c# - 以线程安全的方式写入文件

javascript - 无法调用 Blazor javascript 方法