【问题标题】:Get the approximate size of a struct in Roslyn analyzer在 Roslyn 分析器中获取结构的大致大小
【发布时间】:2021-08-04 15:13:04
【问题描述】:

我想获取作为参数传递给方法的结构的大致大小。我正在使用 Roslyn 分析仪。我们要检查按值传入的结构不大于 128 字节。对于我们的目的,使用 sizeof 或 Marshal.SizeOf 就足够了。

问题在于,据我了解,I cannot use reflection to get the type in the analyzer since reflection is a runtime API。有什么办法可以规避这个问题吗?或者从 Roslyn 中可用的信息中获取结构的大致大小?以下是我迄今为止尝试过的一些事情:

private static void CheckMethodParameters(SyntaxNodeAnalysisContext context)
{
    var methodDeclarationSyntax = (MethodDeclarationSyntax)context.Node;

    foreach (var parameterSyntax in methodDeclarationSyntax.ParameterList.Parameters)
    {
        var parameterSymbol = context.SemanticModel.GetDeclaredSymbol(parameterSyntax);
        if (parameterSymbol == null)
            continue;

        // As expected, none of these have the type I need 
        var entryAssembly = Assembly.GetEntryAssembly();
        var callingAssembly = Assembly.GetCallingAssembly();
        var executingAssemblyAssembly = Assembly.GetExecutingAssembly();

        // This only gets the NamedTypeSymbol, not the type
        var namedTypeSymbol = context.Compilation.GetTypeByMetadataName($"{parameterSymbol.Type.ContainingNamespace}.{parameterSymbol.Type.Name}");

        // None of these work
        var typeFromFullName = Type.GetType($"{parameterSymbol.Type.ContainingNamespace}.{parameterSymbol.Type.Name}, {context.Compilation.Assembly}");
        var assembly = Assembly.Load(context.Compilation.Assembly.ToString());
        var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
        var type = Assembly.Load(context.Compilation.Assembly.Name).GetType($"{parameterSymbol.Type.ContainingNamespace}.{parameterSymbol.Type.Name}");
    }
}

任何帮助将不胜感激。

【问题讨论】:

    标签: c# .net visual-studio roslyn roslyn-code-analysis


    【解决方案1】:

    sizeof 或 Marshal.SizeOf 的使用足以满足我们的目的

    Marshal.SizeOf 将本机缓冲区映射到一组嵌套的托管类,这是一项极其复杂的工作。如果您需要使用Marshal,则您的结构不是 blittable(例如,它不符合where T : unmanaged 限制)。

    因此,您首先需要确定是否需要该功能。

    也就是说,C# 中只有这么多 blittable 类型,您可以轻松编写自己的大小检查代码。您拥有所有基本数值类型(intdouble 等),无论如何它们都具有标准大小,然后您拥有 nintnuint,这取决于您的位数,等等。

    然后你有基本值类型的固定数组 (fixed int arr[10]),计算起来也应该很简单。

    如果您确实需要编组器来支持字符串,您也可以使用它们的属性(CharSetSizeConst)来计算它们的固定大小。

    在所有这些之间,您应该能够涵盖几乎所有的原生结构。没有代码让你做这一切,但它真的不复杂。

    【讨论】:

    • 问题是结构可以有不同类型结构的字段,所以我还需要递归地计算这些字段,这开始变得比它的价值更麻烦。
    • 为什么会有问题?只要你能计算出一个结构体的大小,根据需要递归调用它就很简单了。如果调用一个函数是做某事和不做某事的区别,那么像代码分析这样复杂的事情你不会走得太远!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 2018-12-28
    • 1970-01-01
    • 2021-06-04
    相关资源
    最近更新 更多