|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Data.SqlTypes;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
namespace System.Data
{
/// <summary>
/// Provides a type converter that can be used to populate a list box with available types.
/// </summary>
internal sealed class ColumnTypeConverter : TypeConverter
{
private static readonly Type[] s_types = new Type[] {
typeof(bool),
typeof(byte),
typeof(byte[]),
typeof(char),
typeof(DateTime),
typeof(decimal),
typeof(double),
typeof(Guid),
typeof(short),
typeof(int),
typeof(long),
typeof(object),
typeof(sbyte),
typeof(float),
typeof(string),
typeof(TimeSpan),
typeof(ushort),
typeof(uint),
typeof(ulong),
typeof(SqlInt16),
typeof(SqlInt32),
typeof(SqlInt64),
typeof(SqlDecimal),
typeof(SqlSingle),
typeof(SqlDouble),
typeof(SqlString),
typeof(SqlBoolean),
typeof(SqlBinary),
typeof(SqlByte),
typeof(SqlDateTime),
typeof(SqlGuid),
typeof(SqlMoney),
typeof(SqlBytes),
typeof(SqlChars),
typeof(SqlXml)
};
private StandardValuesCollection? _values;
public ColumnTypeConverter() { }
/// <summary>
/// Gets a value indicating whether this converter can convert an object to the given destination type using the context.
/// </summary>
public override bool CanConvertTo(ITypeDescriptorContext? context, [NotNullWhen(true)] Type? destinationType) =>
destinationType == typeof(InstanceDescriptor) ||
base.CanConvertTo(context, destinationType);
/// <summary>
/// Converts the given value object to the specified destination type.
/// </summary>
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "InstanceDescriptor calls GetType(string) on AssemblyQualifiedName of instance of type we already have in here.")]
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType)
{
ArgumentNullException.ThrowIfNull(destinationType);
if (destinationType == typeof(string))
{
return value != null ? value.ToString() : string.Empty;
}
if (value != null && destinationType == typeof(InstanceDescriptor))
{
object newValue = value;
if (value is string)
{
for (int i = 0; i < s_types.Length; i++)
{
if (s_types[i].ToString().Equals(value))
{
newValue = s_types[i];
}
}
}
if (value is Type || value is string)
{
MethodInfo method = typeof(Type).GetMethod("GetType", new Type[] { typeof(string) })!;
if (method != null)
{
return new InstanceDescriptor(method, new object[] { ((Type)newValue).AssemblyQualifiedName! });
}
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) =>
sourceType == typeof(string) ||
base.CanConvertTo(context, sourceType);
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value != null && value.GetType() == typeof(string))
{
for (int i = 0; i < s_types.Length; i++)
{
if (s_types[i].ToString().Equals(value))
{
return s_types[i];
}
}
return typeof(string);
}
return base.ConvertFrom(context, culture, value!);
}
/// <summary>
/// Gets a collection of standard values for the data type this validator is designed for.
/// </summary>
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context)
{
if (_values == null)
{
object[]? objTypes;
if (s_types != null)
{
objTypes = new object[s_types.Length];
Array.Copy(s_types, objTypes, s_types.Length);
}
else
{
objTypes = null;
}
_values = new StandardValuesCollection(objTypes);
}
return _values;
}
/// <summary>
/// Gets a value indicating whether the list of standard values returned from
/// <see cref='System.ComponentModel.TypeListConverter.GetStandardValues'/> is an exclusive list.
/// </summary>
public override bool GetStandardValuesExclusive(ITypeDescriptorContext? context) => true;
/// <summary>
/// Gets a value indicating whether this object supports a
/// standard set of values that can be picked from a list using the specified context.
/// </summary>
public override bool GetStandardValuesSupported(ITypeDescriptorContext? context) => true;
}
}
|