通过反射确定方法是否不安全

8
我正在寻找一种通过反射过滤掉带有unsafe修饰符的方法的方法。似乎这不是一种方法属性。
有什么办法吗?
编辑:似乎这个信息不在元数据中,至少我在IL中看不到它。但是反编译器在C#视图中显示了unsafe修饰符。有任何关于如何完成此操作的想法吗?
编辑2:根据我的需求,我最终采用了一个检查,假定如果方法的参数之一是指针,或者返回类型是指针,则该方法是不安全的。
    public static bool IsUnsafe(this MethodInfo methodInfo)
    {
        if (HasUnsafeParameters(methodInfo))
        {
            return true;
        }

        return methodInfo.ReturnType.IsPointer;
    }

    private static bool HasUnsafeParameters(MethodBase methodBase)
    {
        var parameters = methodBase.GetParameters();
        bool hasUnsafe = parameters.Any(p => p.ParameterType.IsPointer);

        return hasUnsafe;
    }

这当然无法处理一个不安全的块在方法内执行的情况,但是我只关心方法签名。谢谢!

想要这样做的原因是什么?也许有其他选择。 - djdd87
@GenericTypeTea 我正在通过CodeDom进行一些代码生成。它不支持生成unsafe关键字,因此我想忽略具有unsafe方法的类型。 - Igal Tabachnik
我猜unsafe关键字只是一个标志,告诉编译器:不要在这里生成编译错误,因为我打算使用不安全的代码。反射器可能会检测到不安全的代码并添加关键字。我注意到,如果您在“安全”方法中使用不安全块,则在方法声明中生成反射器中的不安全关键字,因此它不会为其生成块。所以答案是:如果反射器可以检测到mscorlib中的不安全代码,那么您也可以... - Koen
Resharper 还能检测不安全的操作,它会根据这些操作对代码进行着色。例如,您可以查找指针解引用的字节码。 - Adam Ruth
3个回答

5

不幸的是,unsafe关键字只是将方法体包装在一个不安全的块中,并不会发出任何反射可以看到的内容。确保的唯一方法是反汇编方法并查看其中是否有不安全的操作。


我认为如果您可以通过反射看到它,它们应该在MethodInfo上为我们提供一个属性。 - Koen
1
很遗憾,unsafe关键字只是C#的一个特性,而不是IL的。IL具有不安全操作,但没有unsafe关键字的概念。 - Adam Ruth
谢谢,Adam。我接受这个答案,因为这是我自己得出的结论。 - Igal Tabachnik

2
这是 IL 验证器的工作。在 Windows SDK 的 bin 目录中,PEVerify.exe 可以完成这项工作。它验证方法体中的 IL 并标记不安全的 IL,主要是指针。如果对 system.dll 程序集使用它,将会得到一个相当长的列表。
请注意,它拒绝验证 mscorlib.dll,如果您关心的就是这个程序集,那么您会比较困难。复制并重命名它也没有帮助。

0

不要认为没有办法跳出框架。如果你正在反射的代码是你自己的,你可以创建自己的UnsafeAttribute并将这些方法标记为该属性,并在其上进行过滤...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接