Is there a compiler switch to turn off support for Generics in C#?

佐手、 提交于 2019-12-05 15:57:44

Is there some way to turn off support for Generics in VS2010 so that the compiler will flag the offending line ?

Yes, but it is a "nuclear" option:

using System.Collections.Generic;
class Test
{
    static void Main()
    {
        IEnumerable<int> x = null;
    }
}

C:\> csc /langversion:ISO-1 \foo.cs
Microsoft (R) Visual C# 2010 Compiler version 4.0.30319.1
Copyright (C) Microsoft Corporation. All rights reserved.

c:\foo.cs(9,12): error CS1644: Feature 'generics' cannot be used because it is
        not part of the ISO-1 C# language specification

The ISO-1 switch turns off all features that were not in C# 1.0, which might be more features than you want to turn off.

Note that the switch is not intended to be a "emulate C# 1.0 in the C# 2.0 compiler" switch; if you want to run the C# 1.0 compiler, just run it. The switch is intended to identify features that were not present in the particular version and disallow them.

Note that the switch also possibly does not do everything you need it to do. All it does is disallow uses of generic syntax. If you are using a generic type without actually using generic syntax, the switch doesn't catch it.

There's no such specific compiler switch.

You can take a look at the source code (or the decompiled source) and search for usages of generics. Generics can be declared in your project or generic constructs (classes, methods, variables, ...) can be used by your project.

You might want to use reflection to look for generic declarations (classes, methods, fields, ..., but not variables) in your assembly. To look for usage of generics, you need to look into the IL instructions as well. A library like Mono.Cecil can help you with this.

UPDATE

Turns out (with Eric Lippert help, of course) you can compile your code for the C# 1.0 spec with this switch:

/langversion:ISO-1

Apart from generics, you'll also miss on a few things that were added to C# 2.0 and later.

SAMPLE CODE

With Mono.Cecil, you can load an assembly and get all its types:

using Mono.Cecil;
using Mono.Cecil.Rocks;

...

var asm = AssemblyDefinition.ReadAssembly("MyAssembly.dll");
var types = asm.MainModule.GetAllTypes();

And then start making interesting queries against them:

var genericTypes = types.Where(type => type.HasGenericParameters);

var genericMethods = types.
  Select(type => 
    type.Methods.Where(method => method.HasGenericParameters));

var genericFields = types.
  Select(type => 
    type.Fields.Where(field => field.DeclaringType.HasGenericParameters));

var genericMethodInstructions = types.Select(type =>
  type.Methods.Where(method => method.HasBody).
  Select(method => method.Body.Instructions.
    Where(instruction => instruction.Operand is MethodReference).
    Select(instruction => (MethodReference)instruction.Operand).
    Where(methodRef => methodRef.Resolve().HasGenericParameters)));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!