Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/libraries/System.Private.CoreLib/samples/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project>
<!-- Stop inheriting repo-wide settings that break file-based app samples. -->
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<PublishAot>false</PublishAot>
<IsAotCompatible>false</IsAotCompatible>
<IsSourceProject>false</IsSourceProject>
<IsReferenceAssemblyProject>false</IsReferenceAssemblyProject>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Example: Create a DynamicMethod with an owner type to access private members.
// Shows CreateDelegate with a bound instance (instance-style invocation).
// Run: dotnet run DynamicMethod.CtorOwnerType.cs

using System.Reflection;
using System.Reflection.Emit;

OwnerTypeAccess();

Console.WriteLine("Passed.");
return 0;

void OwnerTypeAccess()
{
// A DynamicMethod associated with a type can access its private members.
DynamicMethod changeID = new(
"", typeof(int), [typeof(Example), typeof(int)], typeof(Example));

// Get a FieldInfo for the private field 'id'.
FieldInfo fid = typeof(Example).GetField("id", BindingFlags.NonPublic | BindingFlags.Instance)!;

ILGenerator ilg = changeID.GetILGenerator();
// Push current value of 'id' onto the stack.
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldfld, fid);
// Store the new value.
ilg.Emit(OpCodes.Ldarg_0);
ilg.Emit(OpCodes.Ldarg_1);
ilg.Emit(OpCodes.Stfld, fid);
// Return the old value.
ilg.Emit(OpCodes.Ret);

// Static-style delegate: takes (Example, int), returns old id.
var setId = changeID.CreateDelegate<Func<Example, int, int>>();

Example ex = new(42);
int oldId = setId(ex, 1492);
Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}");

// Instance-style delegate: bind to a specific Example instance.
var setBound = (Func<int, int>)changeID.CreateDelegate(typeof(Func<int, int>), ex);
oldId = setBound(2700);
Console.WriteLine($"Previous id: {oldId}, new id: {ex.ID}");

// Verify
if (ex.ID != 2700)
throw new Exception($"FAIL: expected 2700, got {ex.ID}");
}

// Helper types
public class Example(int id)
{
private int id = id;
Comment on lines +53 to +55
Copy link

Copilot AI Feb 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This field initializer uses the same identifier on both sides (private int id = id;) inside a primary-constructor type. This is very likely to either fail to compile (self-referential field initializer / name collision) or to not do what’s intended. Consider renaming the field (e.g., _id) or assigning the primary-constructor parameter to a differently-named backing field/property to make initialization unambiguous and compilable.

Suggested change
public class Example(int id)
{
private int id = id;
public class Example(int initialId)
{
private int id = initialId;

Copilot uses AI. Check for mistakes.
public int ID => id;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Runnable examples for DynamicMethod XML doc comments.
// Each local function is a self-contained sample referenced by <code> tags in DynamicMethod.cs.
// Run: dotnet run DynamicMethod.Examples.cs

using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;

MetadataAndProperties();
DefineParameterAndGetParameters();
GetILGeneratorAndInvoke();

Console.WriteLine("All examples passed.");
return 0;

void MetadataAndProperties()
{
// Create a dynamic method associated with a module.
DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module);

// Name: the name specified at creation.
Console.WriteLine($"Name: {hello.Name}");

// DeclaringType is always null for dynamic methods.
Console.WriteLine($"DeclaringType: {hello.DeclaringType?.ToString() ?? "(null)"}");

// ReflectedType is always null for dynamic methods.
Console.WriteLine($"ReflectedType: {hello.ReflectedType?.ToString() ?? "(null)"}");

// Module: the module the dynamic method is associated with.
Console.WriteLine($"Module: {hello.Module}");

// Attributes are always Public | Static.
Console.WriteLine($"Attributes: {hello.Attributes}");

// CallingConvention is always Standard.
Console.WriteLine($"CallingConvention: {hello.CallingConvention}");

// ReturnType: the return type specified at creation.
Console.WriteLine($"ReturnType: {hello.ReturnType}");

// ReturnTypeCustomAttributes: no way to set custom attributes on the return type.
ICustomAttributeProvider caProvider = hello.ReturnTypeCustomAttributes;
object[] returnAttributes = caProvider.GetCustomAttributes(true);
Console.WriteLine($"Return type custom attributes: {returnAttributes.Length}");

// InitLocals defaults to true — local variables are zero-initialized.
Console.WriteLine($"InitLocals: {hello.InitLocals}");

// ToString returns the method signature (return type, name, parameter types).
Console.WriteLine($"ToString: {hello.ToString()}");
}

void DefineParameterAndGetParameters()
{
DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module);

// DefineParameter adds metadata such as name and attributes.
// Parameter positions are 1-based; position 0 refers to the return value.
hello.DefineParameter(1, ParameterAttributes.In, "message");
hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn");

// GetParameters retrieves the parameter info.
ParameterInfo[] parameters = hello.GetParameters();
foreach (ParameterInfo p in parameters)
Console.WriteLine($" Param: {p.Name}, {p.ParameterType}, {p.Attributes}");
}

void GetILGeneratorAndInvoke()
{
DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module);
MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!;

// GetILGenerator returns an ILGenerator for emitting the method body.
ILGenerator il = hello.GetILGenerator();
il.Emit(OpCodes.Ldarg_0); // push first arg (string)
il.EmitCall(OpCodes.Call, writeString, null); // Console.WriteLine(string)
il.Emit(OpCodes.Ldarg_1); // push second arg (int)
il.Emit(OpCodes.Ret); // return it

// CreateDelegate produces a strongly-typed delegate for the dynamic method.
Func<string, int, int> hi = hello.CreateDelegate<Func<string, int, int>>();
int retval = hi("Hello from delegate!", 42);
Console.WriteLine($"Delegate returned: {retval}");

// Invoke calls the dynamic method via reflection (slower than a delegate).
object? objRet = hello.Invoke(null, BindingFlags.ExactBinding, null,
["Hello from Invoke!", 99], CultureInfo.InvariantCulture);
Console.WriteLine($"Invoke returned: {objRet}");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// Example: Create a DynamicMethod, emit IL, and execute via delegate and Invoke.
// Referenced by DynamicMethod class overview and GetILGenerator/constructor docs.
// Run: dotnet run DynamicMethod.Overview.cs

using System.Reflection;
using System.Reflection.Emit;

CreateAndInvoke();

Console.WriteLine("Passed.");
return 0;

void CreateAndInvoke()
{
// Create a dynamic method with return type int and two parameters (string, int).
DynamicMethod hello = new("Hello", typeof(int), [typeof(string), typeof(int)], typeof(string).Module);

// Emit a body: print the string argument, then return the int argument.
MethodInfo writeString = typeof(Console).GetMethod("WriteLine", [typeof(string)])!;
ILGenerator il = hello.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.EmitCall(OpCodes.Call, writeString, null);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ret);

// Create a delegate that represents the dynamic method.
Func<string, int, int> hi = hello.CreateDelegate<Func<string, int, int>>();

// Execute via delegate.
int retval = hi("Hello, World!", 42);
Console.WriteLine($"Delegate returned: {retval}");

// Execute via Invoke (slower — requires boxing and array allocation).
object? objRet = hello.Invoke(null, ["Hello via Invoke!", 99]);
Console.WriteLine($"Invoke returned: {objRet}");

// Verify results
if (retval != 42 || objRet is not 99)
throw new Exception("FAIL: unexpected return values");
}
22 changes: 22 additions & 0 deletions src/libraries/System.Private.CoreLib/samples/samples.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"T:System.Reflection.Emit.DynamicMethod": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "method": "CreateAndInvoke", "title": "Creating and invoking a DynamicMethod" },
"M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Reflection.Module)": { "file": "System/Reflection/Emit/DynamicMethod.Overview.cs", "method": "CreateAndInvoke", "title": "Creating a DynamicMethod associated with a module" },
"M:System.Reflection.Emit.DynamicMethod.#ctor(System.String,System.Type,System.Type[],System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "method": "OwnerTypeAccess", "title": "Creating a DynamicMethod with an owner type" },
"P:System.Reflection.Emit.DynamicMethod.Name": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.DeclaringType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.ReflectedType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.Module": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.Attributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.CallingConvention": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.ReturnType": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.ReturnTypeCustomAttributes": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"P:System.Reflection.Emit.DynamicMethod.InitLocals": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"M:System.Reflection.Emit.DynamicMethod.ToString": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "MetadataAndProperties", "title": "DynamicMethod metadata properties" },
"M:System.Reflection.Emit.DynamicMethod.GetParameters": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "DefineParameterAndGetParameters", "title": "Defining and retrieving DynamicMethod parameters" },
"M:System.Reflection.Emit.DynamicMethod.DefineParameter(System.Int32,System.Reflection.ParameterAttributes,System.String)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "DefineParameterAndGetParameters", "title": "Defining and retrieving DynamicMethod parameters" },
"M:System.Reflection.Emit.DynamicMethod.GetILGenerator": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" },
"M:System.Reflection.Emit.DynamicMethod.GetILGenerator(System.Int32)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" },
"M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" },
"M:System.Reflection.Emit.DynamicMethod.CreateDelegate(System.Type,System.Object)": { "file": "System/Reflection/Emit/DynamicMethod.CtorOwnerType.cs", "method": "OwnerTypeAccess", "title": "Creating a bound delegate from a DynamicMethod" },
"M:System.Reflection.Emit.DynamicMethod.Invoke(System.Object,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object[],System.Globalization.CultureInfo)": { "file": "System/Reflection/Emit/DynamicMethod.Examples.cs", "method": "GetILGeneratorAndInvoke", "title": "Emitting IL and invoking a DynamicMethod" }
}
Loading
Loading