using System; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; class Program { static void Main(string[] args) { using (var stream = new System.IO.FileStream("Example.dll", System.IO.FileMode.Open)) using (var peReader = new PEReader(stream)) { var metadataReader = peReader.GetMetadataReader(); foreach (var typeDefHandle in metadataReader.TypeDefinitions) { var typeDef = metadataReader.GetTypeDefinition(typeDefHandle); var genericParameters = typeDef.GetGenericParameters(); foreach (var genericParameterHandle in genericParameters) { var genericParameter = metadataReader.GetGenericParameter(genericParameterHandle); Console.WriteLine($"Name: {metadataReader.GetString(genericParameter.Name)}"); Console.WriteLine($"TypeConstraintCount: {genericParameter.ConstraintCount}"); } } } } }
using System; using System.Reflection.Metadata; using System.Reflection.PortableExecutable; class Program { static void Main(string[] args) { using (var stream = new System.IO.FileStream("Example.dll", System.IO.FileMode.Open)) using (var peReader = new PEReader(stream)) { var metadataReader = peReader.GetMetadataReader(); var methodDefHandle = metadataReader.MethodDefinitions.Single(h => metadataReader.GetString(metadataReader.GetMethodDefinition(h).Name) == "ExampleMethod"); var methodDef = metadataReader.GetMethodDefinition(methodDefHandle); var genericParameters = methodDef.GetGenericParameters(); foreach (var genericParameterHandle in genericParameters) { var genericParameter = metadataReader.GetGenericParameter(genericParameterHandle); Console.WriteLine($"Name: {metadataReader.GetString(genericParameter.Name)}"); Console.WriteLine($"Variance: {genericParameter.Variance}"); } } } }In this example, we load an assembly from disk and retrieve the metadata reader for that assembly. We then find a specific method by its name and retrieve its generic parameters. For each generic parameter, we output its name and variance. Package/Library: System.Reflection.Metadata