* Annotate TypeConverterAttribute so that the ILLinker preserves the ctor on the converter
* Address review feedback & add attributes to ref
* Use custom enum converter type
* Split tests
{
public static readonly System.ComponentModel.TypeConverterAttribute Default;
public TypeConverterAttribute() { }
- public TypeConverterAttribute(string typeName) { }
- public TypeConverterAttribute(System.Type type) { }
+ public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName) { }
+ public TypeConverterAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)] System.Type type) { }
+ [System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicConstructors)]
public string ConverterTypeName { get { throw null; } }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Diagnostics.CodeAnalysis;
+
namespace System.ComponentModel
{
/// <summary>
/// class, using the specified type as the data converter for the object this attribute
/// is bound to.
/// </summary>
- public TypeConverterAttribute(Type type)
+ public TypeConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type type)
{
if (type == null)
{
/// class, using the specified type name as the data converter for the object this attribute
/// is bound to.
/// </summary>
- public TypeConverterAttribute(string typeName)
+ public TypeConverterAttribute([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] string typeName)
{
if (typeName == null)
{
/// Gets the fully qualified type name of the <see cref='System.Type'/> to use as a
/// converter for the object this attribute is bound to.
/// </summary>
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
public string ConverterTypeName { get; }
public override bool Equals(object? obj)
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+
+namespace TypeConverterAttributeTest
+{
+ /// <summary>
+ /// Tests that the public constructors of types passed into System.ComponentModel.TypeConverterAttribute
+ /// are not trimmed out when needed in a trimmed application.
+ /// </summary>
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ // String-based TypeConverterAttribute ctor overload, ensure public parameterless ctor of TypeConverter type is preserved.
+ TypeDescriptor.AddAttributes(typeof(string), new TypeConverterAttribute("TypeConverterAttributeTest.MyStringConverter, project, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
+ var attribute = new DefaultValueAttribute(typeof(string), "Hello, world!");
+ return (string)attribute.Value == "Hello, world!trivia" ? 100 : -1;
+ }
+ }
+
+ internal class MyStringConverter : StringConverter
+ {
+ /// <summary>
+ /// Converts the specified value object to a string object.
+ /// </summary>
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value is string str)
+ {
+ return str + "trivia";
+ }
+
+ throw new NotSupportedException();
+ }
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.ComponentModel;
+using System.Globalization;
+
+namespace TypeConverterAttributeTest
+{
+ /// <summary>
+ /// Tests that the public constructors of types passed into System.ComponentModel.TypeConverterAttribute
+ /// are not trimmed out when needed in a trimmed application.
+ /// </summary>
+ class Program
+ {
+ static int Main(string[] args)
+ {
+ // Type-based TypeConverterAttribute ctor overload, ensure public parameterized ctor of TypeConverter type is preserved.
+ TypeDescriptor.AddAttributes(typeof(DayOfWeek), new TypeConverterAttribute(typeof(MyDayOfWeekConverter)));
+ var attribute = new DefaultValueAttribute(typeof(DayOfWeek), "Friday");
+ return (DayOfWeek)attribute.Value == DayOfWeek.Monday ? 100 : -1;
+ }
+ }
+
+ internal class MyDayOfWeekConverter : TypeConverter
+ {
+ private readonly Type _type;
+
+ public MyDayOfWeekConverter(Type type)
+ {
+ _type = type;
+ }
+
+ /// <summary>
+ /// Converts the specified value object to a DayOfWeek value.
+ /// </summary>
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (_type == typeof(DayOfWeek) && value is string str && str == "Friday")
+ {
+ return DayOfWeek.Monday;
+ }
+
+ throw new NotSupportedException();
+ }
+ }
+}