Skip to content

Commit 464d28a

Browse files
authored
update code (#45431)
1 parent 4bc118b commit 464d28a

File tree

3 files changed

+42
-64
lines changed

3 files changed

+42
-64
lines changed

docs/fundamentals/reflection/how-to-examine-and-instantiate-generic-types-with-reflection.md

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
---
22
title: "How to: Examine and Instantiate Generic Types with Reflection"
33
description: See how to examine and instantiate generic types with reflection. Use the IsGenericType, IsGenericParameter, and GenericParameterPosition properties.
4-
ms.date: "03/30/2017"
4+
ms.date: 03/19/2025
55
dev_langs:
66
- "csharp"
77
- "vb"
8-
- "cpp"
98
helpviewer_keywords:
109
- "reflection, generic types"
1110
- "generics [.NET], reflection"
12-
ms.assetid: f93b03b0-1778-43fc-bc6d-35983d210e74
1311
---
1412
# How to: Examine and instantiate generic types with reflection
1513

@@ -19,52 +17,44 @@ You can create a <xref:System.Type> object that represents a constructed type by
1917

2018
## To examine a generic type and its type parameters
2119

22-
1. Get an instance of <xref:System.Type> that represents the generic type. In the following code, the type is obtained using the C# `typeof` operator (`GetType` in Visual Basic, `typeid` in Visual C++). See the <xref:System.Type> class topic for other ways to get a <xref:System.Type> object. Note that in the rest of this procedure, the type is contained in a method parameter named `t`.
20+
1. Get an instance of <xref:System.Type> that represents the generic type. In the following code, the type is obtained using the C# `typeof` operator (`GetType` in Visual Basic). For other ways to get a <xref:System.Type> object, see <xref:System.Type>. In the rest of this procedure, the type is contained in a method parameter named `t`.
2321

24-
[!code-cpp[HowToGeneric#2](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#2)]
25-
[!code-csharp[HowToGeneric#2](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#2)]
22+
[!code-csharp[HowToGeneric#2](snippets/csharp/generic-types/GenericTypes.cs#2)]
2623
[!code-vb[HowToGeneric#2](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#2)]
2724

2825
2. Use the <xref:System.Type.IsGenericType%2A> property to determine whether the type is generic, and use the <xref:System.Type.IsGenericTypeDefinition%2A> property to determine whether the type is a generic type definition.
2926

30-
[!code-cpp[HowToGeneric#3](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#3)]
31-
[!code-csharp[HowToGeneric#3](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#3)]
27+
[!code-csharp[HowToGeneric#3](snippets/csharp/generic-types/GenericTypes.cs#3)]
3228
[!code-vb[HowToGeneric#3](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#3)]
3329

3430
3. Get an array that contains the generic type arguments, using the <xref:System.Type.GetGenericArguments%2A> method.
3531

36-
[!code-cpp[HowToGeneric#4](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#4)]
37-
[!code-csharp[HowToGeneric#4](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#4)]
32+
[!code-csharp[HowToGeneric#4](snippets/csharp/generic-types/GenericTypes.cs#4)]
3833
[!code-vb[HowToGeneric#4](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#4)]
3934

4035
4. For each type argument, determine whether it is a type parameter (for example, in a generic type definition) or a type that has been specified for a type parameter (for example, in a constructed type), using the <xref:System.Type.IsGenericParameter%2A> property.
4136

42-
[!code-cpp[HowToGeneric#5](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#5)]
43-
[!code-csharp[HowToGeneric#5](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#5)]
37+
[!code-csharp[HowToGeneric#5](snippets/csharp/generic-types/GenericTypes.cs#5)]
4438
[!code-vb[HowToGeneric#5](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#5)]
4539

46-
5. In the type system, a generic type parameter is represented by an instance of <xref:System.Type>, just as ordinary types are. The following code displays the name and parameter position of a <xref:System.Type> object that represents a generic type parameter. The parameter position is trivial information here; it is of more interest when you are examining a type parameter that has been used as a type argument of another generic type.
40+
5. In the type system, a generic type parameter is represented by an instance of <xref:System.Type>, just as ordinary types are. The following code displays the name and parameter position of a <xref:System.Type> object that represents a generic type parameter. The parameter position is trivial information here; it is of more interest when you're examining a type parameter that's been used as a type argument of another generic type.
4741

48-
[!code-cpp[HowToGeneric#6](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#6)]
49-
[!code-csharp[HowToGeneric#6](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#6)]
42+
[!code-csharp[HowToGeneric#6](snippets/csharp/generic-types/GenericTypes.cs#6)]
5043
[!code-vb[HowToGeneric#6](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#6)]
5144

5245
6. Determine the base type constraint and the interface constraints of a generic type parameter by using the <xref:System.Type.GetGenericParameterConstraints%2A> method to obtain all the constraints in a single array. Constraints are not guaranteed to be in any particular order.
5346

54-
[!code-cpp[HowToGeneric#7](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#7)]
55-
[!code-csharp[HowToGeneric#7](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#7)]
47+
[!code-csharp[HowToGeneric#7](snippets/csharp/generic-types/GenericTypes.cs#7)]
5648
[!code-vb[HowToGeneric#7](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#7)]
5749

5850
7. Use the <xref:System.Type.GenericParameterAttributes%2A> property to discover the special constraints on a type parameter, such as requiring that it be a reference type. The property also includes values that represent variance, which you can mask off as shown in the following code.
5951

60-
[!code-cpp[HowToGeneric#8](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#8)]
61-
[!code-csharp[HowToGeneric#8](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#8)]
52+
[!code-csharp[HowToGeneric#8](snippets/csharp/generic-types/GenericTypes.cs#8)]
6253
[!code-vb[HowToGeneric#8](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#8)]
6354

64-
8. The special constraint attributes are flags, and the same flag (<xref:System.Reflection.GenericParameterAttributes.None?displayProperty=nameWithType>) that represents no special constraints also represents no covariance or contravariance. Thus, to test for either of these conditions you must use the appropriate mask. In this case, use <xref:System.Reflection.GenericParameterAttributes.SpecialConstraintMask?displayProperty=nameWithType> to isolate the special constraint flags.
55+
8. The special constraint attributes are flags, and the same flag (<xref:System.Reflection.GenericParameterAttributes.None?displayProperty=nameWithType>) that represents no special constraints also represents no covariance or contravariance. Thus, to test for either of these conditions, you must use the appropriate mask. In this case, use <xref:System.Reflection.GenericParameterAttributes.SpecialConstraintMask?displayProperty=nameWithType> to isolate the special constraint flags.
6556

66-
[!code-cpp[HowToGeneric#9](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#9)]
67-
[!code-csharp[HowToGeneric#9](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#9)]
57+
[!code-csharp[HowToGeneric#9](snippets/csharp/generic-types/GenericTypes.cs#9)]
6858
[!code-vb[HowToGeneric#9](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#9)]
6959

7060
## Construct an instance of a generic type
@@ -73,26 +63,22 @@ A generic type is like a template. You cannot create instances of it unless you
7363

7464
1. Get a <xref:System.Type> object that represents the generic type. The following code gets the generic type <xref:System.Collections.Generic.Dictionary%602> in two different ways: by using the <xref:System.Type.GetType%28System.String%29?displayProperty=nameWithType> method overload with a string describing the type, and by calling the <xref:System.Type.GetGenericTypeDefinition%2A> method on the constructed type `Dictionary\<String, Example>` (`Dictionary(Of String, Example)` in Visual Basic). The <xref:System.Type.MakeGenericType%2A> method requires a generic type definition.
7565

76-
[!code-cpp[HowToGeneric#10](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#10)]
77-
[!code-csharp[HowToGeneric#10](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#10)]
66+
[!code-csharp[HowToGeneric#10](snippets/csharp/generic-types/GenericTypes.cs#10)]
7867
[!code-vb[HowToGeneric#10](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#10)]
7968

8069
2. Construct an array of type arguments to substitute for the type parameters. The array must contain the correct number of <xref:System.Type> objects, in the same order as they appear in the type parameter list. In this case, the key (first type parameter) is of type <xref:System.String>, and the values in the dictionary are instances of a class named `Example`.
8170

82-
[!code-cpp[HowToGeneric#11](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#11)]
83-
[!code-csharp[HowToGeneric#11](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#11)]
71+
[!code-csharp[HowToGeneric#11](snippets/csharp/generic-types/GenericTypes.cs#11)]
8472
[!code-vb[HowToGeneric#11](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#11)]
8573

8674
3. Call the <xref:System.Type.MakeGenericType%2A> method to bind the type arguments to the type parameters and construct the type.
8775

88-
[!code-cpp[HowToGeneric#12](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#12)]
89-
[!code-csharp[HowToGeneric#12](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#12)]
76+
[!code-csharp[HowToGeneric#12](snippets/csharp/generic-types/GenericTypes.cs#12)]
9077
[!code-vb[HowToGeneric#12](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#12)]
9178

9279
4. Use the <xref:System.Activator.CreateInstance%28System.Type%29> method overload to create an object of the constructed type. The following code stores two instances of the `Example` class in the resulting `Dictionary<String, Example>` object.
9380

94-
[!code-cpp[HowToGeneric#13](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#13)]
95-
[!code-csharp[HowToGeneric#13](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#13)]
81+
[!code-csharp[HowToGeneric#13](snippets/csharp/generic-types/GenericTypes.cs#13)]
9682
[!code-vb[HowToGeneric#13](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#13)]
9783

9884
## Example
@@ -105,8 +91,7 @@ The code example defines a set of test types, including a generic type that illu
10591

10692
The example constructs a type from the <xref:System.Collections.Generic.Dictionary%602> class by creating an array of type arguments and calling the <xref:System.Type.MakeGenericType%2A> method. The program compares the <xref:System.Type> object constructed using <xref:System.Type.MakeGenericType%2A> with a <xref:System.Type> object obtained using `typeof` (`GetType` in Visual Basic), demonstrating that they are the same. Similarly, the program uses the <xref:System.Type.GetGenericTypeDefinition%2A> method to obtain the generic type definition of the constructed type, and compares it to the <xref:System.Type> object representing the <xref:System.Collections.Generic.Dictionary%602> class.
10793

108-
[!code-cpp[HowToGeneric#1](../../../samples/snippets/cpp/VS_Snippets_CLR/HowToGeneric/cpp/ur.cpp#1)]
109-
[!code-csharp[HowToGeneric#1](../../../samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs#1)]
94+
[!code-csharp[HowToGeneric#1](snippets/csharp/generic-types/GenericTypes.cs#1)]
11095
[!code-vb[HowToGeneric#1](../../../samples/snippets/visualbasic/VS_Snippets_CLR/HowToGeneric/VB/ur.vb#1)]
11196

11297
## See also

samples/snippets/csharp/VS_Snippets_CLR/HowToGeneric/CS/ur.cs renamed to docs/fundamentals/reflection/snippets/csharp/generic-types/GenericTypes.cs

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,23 @@
1-
// Example code for How to: Discover and Manipulate Generic Types
21
//<Snippet1>
3-
using System;
42
using System.Reflection;
5-
using System.Collections.Generic;
63

74
// Define an example interface.
8-
public interface ITestArgument {}
5+
public interface ITestArgument { }
96

107
// Define an example base class.
11-
public class TestBase {}
8+
public class TestBase { }
129

1310
// Define a generic class with one parameter. The parameter
1411
// has three constraints: It must inherit TestBase, it must
1512
// implement ITestArgument, and it must have a parameterless
1613
// constructor.
17-
public class Test<T> where T : TestBase, ITestArgument, new() {}
14+
public class Test<T> where T : TestBase, ITestArgument, new() { }
1815

1916
// Define a class that meets the constraints on the type
2017
// parameter of class Test.
2118
public class TestArgument : TestBase, ITestArgument
2219
{
23-
public TestArgument() {}
20+
public TestArgument() { }
2421
}
2522

2623
public class Example
@@ -42,7 +39,7 @@ private static void DisplayGenericType(Type t)
4239

4340
//<Snippet5>
4441
Console.WriteLine($" List {typeParameters.Length} type arguments:");
45-
foreach( Type tParam in typeParameters )
42+
foreach (Type tParam in typeParameters)
4643
{
4744
if (tParam.IsGenericParameter)
4845
{
@@ -56,34 +53,23 @@ private static void DisplayGenericType(Type t)
5653
//</Snippet5>
5754
}
5855

59-
// The following method displays information about a generic
60-
// type parameter. Generic type parameters are represented by
61-
// instances of System.Type, just like ordinary types.
62-
//<Snippet6>
56+
// Displays information about a generic type parameter.
6357
private static void DisplayGenericParameter(Type tp)
6458
{
59+
//<Snippet6>
6560
Console.WriteLine($" Type parameter: {tp.Name} position {tp.GenericParameterPosition}");
6661
//</Snippet6>
6762

6863
//<Snippet7>
69-
Type classConstraint = null;
70-
71-
foreach(Type iConstraint in tp.GetGenericParameterConstraints())
64+
foreach (Type iConstraint in tp.GetGenericParameterConstraints())
7265
{
7366
if (iConstraint.IsInterface)
7467
{
7568
Console.WriteLine($" Interface constraint: {iConstraint}");
7669
}
7770
}
7871

79-
if (classConstraint != null)
80-
{
81-
Console.WriteLine($" Base type constraint: {tp.BaseType}");
82-
}
83-
else
84-
{
85-
Console.WriteLine(" Base type constraint: None");
86-
}
72+
Console.WriteLine($" Base type constraint: {tp.BaseType ?? tp.BaseType: None}");
8773
//</Snippet7>
8874

8975
//<Snippet8>
@@ -122,7 +108,7 @@ public static void Main()
122108
{
123109
// Two ways to get a Type object that represents the generic
124110
// type definition of the Dictionary class.
125-
//
111+
126112
//<Snippet10>
127113
// Use the typeof operator to create the generic type
128114
// definition directly. To specify the generic type definition,
@@ -135,7 +121,7 @@ public static void Main()
135121
// You can also obtain the generic type definition from a
136122
// constructed class. In this case, the constructed class
137123
// is a dictionary of Example objects, with String keys.
138-
Dictionary<string, Example> d2 = new Dictionary<string, Example>();
124+
Dictionary<string, Example> d2 = [];
139125
// Get a Type object that represents the constructed type,
140126
// and from that get the generic type definition. The
141127
// variables d1 and d4 contain the same type.
@@ -156,7 +142,7 @@ public static void Main()
156142
// is of type string, and the type to be contained in the
157143
// dictionary is Example.
158144
//<Snippet11>
159-
Type[] typeArgs = {typeof(string), typeof(Example)};
145+
Type[] typeArgs = [typeof(string), typeof(Example)];
160146
//</Snippet11>
161147

162148
// Construct the type Dictionary<String, Example>.
@@ -165,16 +151,13 @@ public static void Main()
165151
//</Snippet12>
166152

167153
DisplayGenericType(constructed);
168-
169154
//<Snippet13>
170-
object o = Activator.CreateInstance(constructed);
155+
_ = Activator.CreateInstance(constructed);
171156
//</Snippet13>
172157

173158
Console.WriteLine("\r\nCompare types obtained by different methods:");
174-
Console.WriteLine(" Are the constructed types equal? {0}",
175-
(d2.GetType()==constructed));
176-
Console.WriteLine(" Are the generic definitions equal? {0}",
177-
(d1==constructed.GetGenericTypeDefinition()));
159+
Console.WriteLine($" Are the constructed types equal? {d2.GetType() == constructed}");
160+
Console.WriteLine($" Are the generic definitions equal? {d1 == constructed.GetGenericTypeDefinition()}");
178161

179162
// Demonstrate the DisplayGenericType and
180163
// DisplayGenericParameter methods with the Test class
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9</TargetFramework>
5+
<LangVersion>latest</LangVersion>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>

0 commit comments

Comments
 (0)