Consider the following C# code:
var methodBuilder1 = typeBuilder.DefineMethod("GetMedalIds", MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int[]), null);
var methodBuilder2 = typeBuilder.DefineMethod("GetMedalIds", MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int[]), null);
First, note that the arguments into DefineMethod
are identical (and arbitrary), and typeBuilder
is the same instance in both cases. With this in mind, I have discovered the methodBuilder1
and methodBuilder2
both point to the same instance (at least methodBuiilder1 == methodBuilder2
is always true), leading me to assume that if the method builder hasn't already been defined, type builder defines it, otherwise it returns the already defined method builder.
My question is this: The comments on DefineMethod(...)
says nothing about the above, so are my assumptions GUARANTEED to always be true as far as the C# specification is concerned, or is it an implementation detail that is subject to change? .
CodePudding user response:
Assumptions in the question are incorrect. The instances are logically equivalent (==
returns true), but point to separate instances. You can test this with Object.ReferenceEquals(...)
.
Use this answer for dotnet core 3.1:
using System;
using System.Reflection;
using System.Reflection.Emit;
namespace MethodBuilderDemo
{
class Program
{
static void Main(string[] args)
{
AssemblyName asmName = new AssemblyName("DemoMethodBuilder1");
AssemblyBuilder demoAssembly = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(Guid.NewGuid().ToString()), AssemblyBuilderAccess.Run);
ModuleBuilder demoModule = demoAssembly.DefineDynamicModule(asmName.Name);
TypeBuilder demoType = demoModule.DefineType("DemoType",TypeAttributes.Public | TypeAttributes.Abstract);
var methodBuilder1 = demoType.DefineMethod("GetMedalIds", MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int[]), null);
var methodBuilder2 = demoType.DefineMethod("GetMedalIds", MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(int[]), null);
Console.WriteLine($"==: {methodBuilder1 == methodBuilder2}");
Console.WriteLine($"ref equals: {Object.ReferenceEquals(methodBuilder1, methodBuilder2)}");
}
}
}
gives
==: True
ref equals: False