【问题标题】:Generic type compile time evaluation and method inlining泛型编译时评估和方法内联
【发布时间】:2019-09-20 06:10:06
【问题描述】:

假设我有以下方法:

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public void EmptyMethod<T>(T inputVariable) where T: parentType
    {
        if(typeof(T) is childType)
        {
            // do something
        }

        if(typeof(T) is anotherChildType)
        {
            // do other things
        }
    }

我在程序的不同位置使用此方法,但是当我检查发布版本的 MSIL 时,我看到以下内容: 1.方法没有内联。 2. 但更糟糕的是 - 该方法在运行时评估 inputVariable 的类型(这是预期的 - 请参阅此链接 https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching)。

但我希望在编译时内联这个方法和 inputVariable 的类型。

【问题讨论】:

  • 看来你的泛型方法不应该是泛型的。
  • 这并不能保证它会内联该方法 (softwareengineering.stackexchange.com/a/293899)。
  • 我怀疑您正在尝试使用您从另一个堆栈(可能是 C++)中学到的课程,而不怀疑这些课程是否真的适用于 C#。
  • 所有适用于 C++ 的东西都适用于 C#,除了内存管理和其他一些低级的东西

标签: c# generics compiler-optimization


【解决方案1】:

检查 MSIL 与内联无关,因为这是由 JIT 完成的 - 第二 .NET 代码的编译阶段。

MSIL 仍然包含不知道它将用于什么类型的通用代码。这就是 .NET 泛型可以跨编译单元工作的原因。

看起来这根本不应该是通用代码,而是两个具有相同方法名称的重载:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EmptyMethod(childType inputVariable)
{
    // do something
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EmptyMethod(anotherChildType inputVariable)
{
    // do other things
}

如果您发现自己在通用代码中进行类型检查,这通常表明您选择了错误的工具来完成这项工作。

【讨论】:

    猜你喜欢
    • 2011-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多