Skip to content
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Reflection.Context" Version="10.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Context;

namespace ConsoleApplication1
{
//<Snippet1>
//A blank example attribute.
class MyAttribute : Attribute
{
}

//Reflection context with custom rules.
class MyCustomReflectionContext : CustomReflectionContext
{
//Called whenever the reflection context checks for custom attributes.
protected override IEnumerable<object> GetCustomAttributes(MemberInfo member, IEnumerable<object> declaredAttributes)
{
//Add example attribute to "To*" members.
if (member.Name.StartsWith("To"))
{
yield return new MyAttribute();
}
//Keep existing attributes as well.
foreach (var attr in declaredAttributes) yield return attr;
}
}

class Program
{
static void Main(string[] args)
{
MyCustomReflectionContext mc = new MyCustomReflectionContext();
Type t = typeof(String);

//A representation of the type in the default reflection context.
TypeInfo ti = t.GetTypeInfo();

//A representation of the type in the customized reflection context.
TypeInfo myTI = mc.MapType(ti);

//Display all the members of the type and their attributes.
foreach (MemberInfo m in myTI.DeclaredMembers)
{
Console.WriteLine(m.Name + ":");
foreach (Attribute cd in m.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}
}

Console.WriteLine();

//The "ToString" member as represented in the default reflection context.
MemberInfo mi1 = ti.GetDeclaredMethods("ToString").FirstOrDefault();

//All the attributes of "ToString" in the default reflection context.
Console.WriteLine("'ToString' Attributes in Default Reflection Context:");
foreach (Attribute cd in mi1.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}

Console.WriteLine();

//The same member in the custom reflection context.
mi1 = myTI.GetDeclaredMethods("ToString").FirstOrDefault();

//All its attributes, for comparison. MyAttribute is now included.
Console.WriteLine("'ToString' Attributes in Custom Reflection Context:");
foreach (Attribute cd in mi1.GetCustomAttributes())
{
Console.WriteLine(cd.GetType());
}

Console.ReadLine();
}
}
//</Snippet1>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: System.Reflection.Context.CustomReflectionContext class
description: Learn about the System.Reflection.Context.CustomReflectionContext class.
ms.date: 02/12/2026
ai-usage: ai-assisted
---
# System.Reflection.Context.CustomReflectionContext class

[!INCLUDE [context](includes/context.md)]

<xref:System.Reflection.Context.CustomReflectionContext> provides a way for you to add or remove custom attributes from reflection objects, or add dummy properties to those objects, without re-implementing the complete reflection model. The default <xref:System.Reflection.Context.CustomReflectionContext> simply wraps reflection objects without making any changes, but by subclassing and overriding the relevant methods, you can add, remove, or change the attributes that apply to any reflected parameter or member, or add new properties to a reflected type.

For example, suppose that your code follows the convention of applying a particular attribute to factory methods, but you're now required to work with third-party code that lacks attributes. You can use <xref:System.Reflection.Context.CustomReflectionContext> to specify a rule for identifying the objects that should have attributes and to supply the objects with those attributes when they're viewed from your code.

To use <xref:System.Reflection.Context.CustomReflectionContext> effectively, the code that uses the reflected objects must support the notion of specifying a reflection context, instead of assuming that all reflected objects are associated with the runtime reflection context. Many reflection methods in the .NET Framework provide a <xref:System.Reflection.ReflectionContext> parameter for this purpose.

To modify the attributes that are applied to a reflected parameter or member, override the <xref:System.Reflection.Context.CustomReflectionContext.GetCustomAttributes%28System.Reflection.ParameterInfo%2CSystem.Collections.Generic.IEnumerable%7BSystem.Object%7D%29> or <xref:System.Reflection.Context.CustomReflectionContext.GetCustomAttributes%28System.Reflection.MemberInfo%2CSystem.Collections.Generic.IEnumerable%7BSystem.Object%7D%29> method. These methods take the reflected object and the list of attributes under its current reflection context, and return the list of attributes it should have under the custom reflection context.

> [!WARNING]
> <xref:System.Reflection.Context.CustomReflectionContext> methods should not access the list of attributes of a reflected object or method directly by calling the <xref:System.Reflection.MemberInfo.GetCustomAttributes%2A> method on the provided <xref:System.Reflection.MemberInfo> or <xref:System.Reflection.ParameterInfo> instance, but should instead use the `declaredAttributes` list, which is passed as a parameter to the <xref:System.Reflection.Context.CustomReflectionContext.GetCustomAttributes%2A> method overloads.

To add properties to a reflected type, override the <xref:System.Reflection.Context.CustomReflectionContext.AddProperties%2A> method. The method accepts a parameter that specifies the reflected type, and returns a list of additional properties. You should use the <xref:System.Reflection.Context.CustomReflectionContext.CreateProperty%2A> method to create property objects to return. You can specify delegates when creating the property that serve as the property accessor, and you can omit one of the accessors to create a read-only or write-only property. Note that such dummy properties have no metadata or Common Intermediate Language (CIL) backing.

> [!WARNING]
>
> - Be cautious about equality among reflected objects when you work with reflection contexts, because objects might represent the same reflected object in multiple contexts. You can use the <xref:System.Reflection.Context.CustomReflectionContext.MapType%2A> method to obtain a particular reflection context's version of a reflected object.
> - A <xref:System.Reflection.Context.CustomReflectionContext> object alters the attributes returned by a particular reflection object, such as those obtained by the <xref:System.Reflection.MemberInfo.GetCustomAttributes%2A> method. It doesn't alter the custom attribute data returned by the <xref:System.Reflection.MemberInfo.GetCustomAttributesData%2A> method, and these two lists won't match when you use a custom reflection context.

## Example

The following example demonstrates how to subclass <xref:System.Reflection.Context.CustomReflectionContext> to add a custom attribute to all the members of a given type whose names begin with "To". To run this code, paste it into an empty console project and add a reference to the `System.Reflection.Context` NuGet package.

:::code language="csharp" source="./snippets/system-reflection-context-customreflectioncontext/csharp/program.cs" id="Snippet1":::
2 changes: 2 additions & 0 deletions docs/fundamentals/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1394,6 +1394,8 @@ items:
href: runtime-libraries/system-type-gettype.md
- name: MakeGenericType method
href: runtime-libraries/system-type-makegenerictype.md
- name: The CustomReflectionContext class
href: runtime-libraries/system-reflection-context-customreflectioncontext.md
- name: Graphics
items:
- name: Supplemental API remarks
Expand Down