.net - 如何检测哪种 .NET 语言正在调用我的代码

标签 .net reflection cil

我正在构建一个生成用户代理字符串的库,该字符串报告一些漂亮的数据,如操作系统版本和currently installed .NET Framework versions。 .我很好奇:

是否可以以编程方式检测哪种语言正在调用我的库?还是源语言在编译成 CIL 后完全不透明?

最佳答案

编辑:我把它变成了 small library它封装了一些启发式方法并使其易于调用。

我想出了一个似乎可以很好地满足我自己需求的启发式方法。

@Don 的回答和这些问题给了我一些提示:

注意事项:

  • 仅区分 VB.NET 和 C#,不区分任何其他 CLR 语言。如果没有足够的 VB 证据,则假定为 C#。
  • 这是一个有根据的猜测,因此误报的可能性 > 0。
  • 一些提示基于编译器实现细节,可能会发生变化。
  • 这似乎也适用于 Mono,但 YMMV。
  • 这是一种昂贵的反射,因此在现实生活中您可能希望将其包装在 Lazy<> 中或其他一些机制来确保它只被调用一次。
  • 正如@HABO 所提到的,这可能是也可能不是非常有用的信息。我主要是想看看能不能做到。

var lang = DetectAssemblyLanguage(Assembly.GetCallingAssembly());

public static string DetectAssemblyLanguage(Assembly assembly)
{
    var referencedAssemblies = assembly
        .GetReferencedAssemblies()
        .Select(x => x.Name);

    var types = assembly
        .GetTypes();

    // Biggest hint: almost all VB.NET projects have a
    // hidden reference to the Microsoft.VisualBasic assembly
    bool referenceToMSVB = referencedAssemblies.Contains("Microsoft.VisualBasic");

    // VB.NET projects also typically reference the special
    // (YourProject).My.My* types that VB generates
    bool areMyTypesPresent = types.Select(x => x.FullName).Where(x => x.Contains(".My.My")).Any();

    // If a VB.NET project uses any anonymous types,
    // the compiler names them like VB$AnonymousType_0`1
    bool generatedVbNames = types.Select(x => x.Name).Where(x => x.StartsWith("VB$")).Any();

    // If a C# project uses dynamic, it'll have a reference to Microsoft.CSharp
    bool referenceToMSCS = referencedAssemblies.Contains("Microsoft.CSharp");

    // If a C# project uses any anonymous types,
    // the compiler names them like <>f__AnonymousType0`1
    bool generatedCsNames = types.Select(x => x.Name).Where(x => x.StartsWith("<>")).Any();

    var evidenceForVb = new bool[] 
    {
        referenceToMSVB,
        myTypesPresent,
        vbGeneratedNames
    };

    var evidenceForCsharp = new bool[] {
        true, // freebie. ensures ties go to C#
        referenceToMSCS,
        csGeneratedNames
    };

    var scoreForVb = evidenceForVb.Count(x => x)
                     - evidenceForCsharp.Count(x => x);

    // In the case of a tie, C# is assumed
    return scoreForVb > 0
        ? "vb"
        : "cs";
}

关于.net - 如何检测哪种 .NET 语言正在调用我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33161188/

相关文章:

haskell - 在临时多态函数和参数多态函数之间转换的好方法

c# - 程序集.加载+依赖项

c# - 动态创建方法,并执行它

c# - 注入(inject)从 MethodInfo.GetMethodBody() 导出的 byte[]

c# - JavaScript 不接受文本框的值

c# - 在 C# 中解析负双数时出现异常

c# - 如何在 C# 中从字符串创建泛型类?

.net - AssemblyBuilder 引用程序集

.net - .NET 文件的指令级调试

.net - 在 .NET 和 Mono 中使用相同的 log4net 程序集