Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Commit

Permalink
Implement System.ComponentModel.VersionConverter
Browse files Browse the repository at this point in the history
VersionConverter is a new System.ComponentModel.TypeConverter subclass that handle conversions between string and System.Version.
  • Loading branch information
0xced committed Jun 27, 2018
1 parent dc54c45 commit f93bc30
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,15 @@ public TimeSpanConverter() { }
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; }
public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; }
}
public partial class VersionConverter : System.ComponentModel.TypeConverter
{
public VersionConverter() { }
public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType) { throw null; }
public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType) { throw null; }
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { throw null; }
public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) { throw null; }
public override bool IsValid(System.ComponentModel.ITypeDescriptorContext context, object value) { throw null; }
}
public partial class TypeConverter
{
public TypeConverter() { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<Compile Include="System\ComponentModel\UInt32Converter.cs" />
<Compile Include="System\ComponentModel\UInt64Converter.cs" />
<Compile Include="System\ComponentModel\UriTypeConverter.cs" />
<Compile Include="System\ComponentModel\VersionConverter.cs" />
<Compile Include="System\Timers\ElapsedEventArgs.cs" />
<Compile Include="System\Timers\ElapsedEventHandler.cs" />
<Compile Include="System\Timers\Timer.cs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ internal ReflectTypeDescriptionProvider()
[typeof(TimeSpan)] = typeof(TimeSpanConverter),
[typeof(Guid)] = typeof(GuidConverter),
[typeof(Uri)] = typeof(UriTypeConverter),
[typeof(Version)] = typeof(VersionConverter),
[typeof(Color)] = typeof(ColorConverter),
[typeof(Point)] = typeof(PointConverter),
[typeof(Rectangle)] = typeof(RectangleConverter),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Globalization;

namespace System.ComponentModel
{
/// <summary>
/// <para>Provides a type converter to convert Version objects to and
/// from various other representations.</para>
/// </summary>
public class VersionConverter : TypeConverter
{
/// <summary>
/// <para>Gets a value indicating whether this converter can convert an object in the
/// given source type to a Version.</para>
/// </summary>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == null)
throw new ArgumentNullException(nameof(sourceType));

return sourceType == typeof(string) || sourceType == typeof(Version);
}

/// <summary>
/// <para>Gets a value indicating whether this converter can
/// convert an object to the given destination type using the context.</para>
/// </summary>
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(string) || destinationType == typeof(Version);
}

/// <summary>
/// <para>Converts the given object to a Version.</para>
/// </summary>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is string versionString)
{
// Let the Version constructor throw any informative exceptions
return new Version(versionString);
}

if (value is Version version)
{
return new Version(version.Major, version.Minor, version.Build, version.Revision); // return new instance
}

throw GetConvertFromException(value);
}

/// <summary>
/// <para>Converts the given value object to
/// the specified destination type using the specified context and arguments.</para>
/// </summary>
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException(nameof(destinationType));
}

if (value is Version version)
{
if (destinationType == typeof(string))
return version.ToString();

if (destinationType == typeof(Version))
return new Version(version.Major, version.Minor, version.Build, version.Revision);
}

throw GetConvertToException(value, destinationType);
}

public override bool IsValid(ITypeDescriptorContext context, object value)
{
if (value is string version)
{
return Version.TryParse(version, out Version _);
}
return value is Version;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public class Perf_TypeDescriptorTests
[InlineData(typeof(ClassIBase), typeof(IBaseConverter))]
[InlineData(typeof(ClassIDerived), typeof(IBaseConverter))]
[InlineData(typeof(Uri), typeof(UriTypeConverter))]
[InlineData(typeof(Version), typeof(VersionConverter))]
public static void GetConverter(Type typeToConvert, Type expectedConverter)
{
const int innerIterations = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
<Compile Include="UInt32ConverterTests.cs" />
<Compile Include="UInt64ConverterTests.cs" />
<Compile Include="UriTypeConverterTests.cs" />
<Compile Include="VersionConverterTests.cs" />
<Compile Include="Drawing\StringTypeConverterTestBase.cs" />
<Compile Include="TimerTests.cs" />
<Compile Include="ContainerTests.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ class FooBarDerived : FooBarBase
new Tuple<Type, Type> (typeof(ClassIBase), typeof(IBaseConverter)),
new Tuple<Type, Type> (typeof(ClassIDerived), typeof(IBaseConverter)),
new Tuple<Type, Type> (typeof(Uri), typeof(UriTypeConverter)),
new Tuple<Type, Type> (typeof(Version), typeof(VersionConverter)),
new Tuple<Type, Type> (typeof(CultureInfo), typeof(CultureInfoConverter))
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Xunit;

namespace System.ComponentModel.Tests
{
public class VersionConverterTests : ConverterTestBase
{
private static VersionConverter s_converter = new VersionConverter();

[Fact]
public static void CanConvertFrom_WithContext()
{
CanConvertFrom_WithContext(new object[2, 2]
{
{ typeof(string), true },
{ typeof(Version), true }
},
VersionConverterTests.s_converter);
}

[Fact]
public static void ConvertFrom_WithContext()
{
ConvertFrom_WithContext(new object[3, 3]
{
{"1.2", new Version(1, 2), null},
{"1.2.3", new Version(1, 2, 3), null},
{"1.2.3.4", new Version(1, 2, 3, 4), null}
},
VersionConverterTests.s_converter);
}

[Fact]
public static void ConvertFrom_WithContext_Negative()
{
Assert.Throws<NotSupportedException>(
() => VersionConverterTests.s_converter.ConvertFrom(TypeConverterTests.s_context, null, null));
Assert.Throws<ArgumentException>(
() => VersionConverterTests.s_converter.ConvertFrom(TypeConverterTests.s_context, null, ""));
Assert.Throws<ArgumentException>(
() => VersionConverterTests.s_converter.ConvertFrom(TypeConverterTests.s_context, null, "1"));
}
}
}

0 comments on commit f93bc30

Please sign in to comment.