Skip to content

Commit cc1bffe

Browse files
Copilotjkotas
andauthored
Improve TypeBuilderInstantiation error messages to guide users to TypeBuilder static methods (#118638)
Fixes #118506 Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
1 parent 718c776 commit cc1bffe

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed

src/libraries/System.Private.CoreLib/src/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3014,6 +3014,9 @@
30143014
<data name="NotSupported_CreateInstanceWithTypeBuilder" xml:space="preserve">
30153015
<value>CreateInstance cannot be used with an object of type TypeBuilder.</value>
30163016
</data>
3017+
<data name="NotSupported_TypeBuilderInstantiation_ResolvingMembers" xml:space="preserve">
3018+
<value>TypeBuilder generic instantiation does not support resolving members. Use TypeBuilder.{0} instead.</value>
3019+
</data>
30173020
<data name="NotSupported_DBNullSerial" xml:space="preserve">
30183021
<value>Only one DBNull instance may exist, and calls to DBNull deserialization methods are not allowed.</value>
30193022
</data>

src/libraries/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,22 @@ public override Type? BaseType
161161
}
162162
}
163163
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
164-
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
164+
protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[] types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetConstructor))); }
165165

166166
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
167-
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); }
167+
public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetConstructor))); }
168168

169169
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
170-
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(); }
170+
protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder? binder, CallingConventions callConvention, Type[]? types, ParameterModifier[]? modifiers) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetMethod))); }
171171

172172
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
173-
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); }
173+
public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetMethod))); }
174174

175175
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
176-
public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(); }
176+
public override FieldInfo GetField(string name, BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetField))); }
177177

178178
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)]
179-
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); }
179+
public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(SR.Format(SR.NotSupported_TypeBuilderInstantiation_ResolvingMembers, nameof(TypeBuilder.GetField))); }
180180

181181
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
182182
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)]
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Xunit;
5+
6+
namespace System.Reflection.Emit.Tests
7+
{
8+
public class TypeBuilderInstantiationErrorMessageTests
9+
{
10+
[Fact]
11+
public void TypeBuilderInstantiation_ThrowsWithHelpfulMessage()
12+
{
13+
TypeBuilder type = Helpers.DynamicType(TypeAttributes.Public);
14+
15+
type.DefineGenericParameters("T");
16+
17+
Type instantiatedType = type.MakeGenericType(typeof(string));
18+
19+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetConstructor), () => instantiatedType.GetConstructor(Type.EmptyTypes));
20+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetConstructor), () => instantiatedType.GetConstructors());
21+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetMethod), () => instantiatedType.GetMethod("Test"));
22+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetMethod), () => instantiatedType.GetMethods());
23+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetField), () => instantiatedType.GetField("_test"));
24+
AssertThrowsWithHelpfulMessage(nameof(TypeBuilder.GetField), () => instantiatedType.GetFields());
25+
26+
static void AssertThrowsWithHelpfulMessage(string suggestedAlternative, TestDelegate code)
27+
{
28+
NotSupportedException ex = Assert.Throws<NotSupportedException>(code);
29+
Assert.Contains($"TypeBuilder.{suggestedAlternative}", ex.Message);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)