未验证 提交 9fedcc55 编写于 作者: L Layomi Akinrinade 提交者: GitHub

Fix binding logic for dictionaries with complex elements (#89045)

上级 8e9222b9
......@@ -731,7 +731,7 @@ void Emit_BindAndAddLogic_ForElement(string parsedKeyExpr)
""");
}
EmitBindCoreCall(elementType, $"{Identifier.element}!", Identifier.section, InitializationKind.None);
EmitBindCoreCall(elementType, $"{Identifier.element}", Identifier.section, InitializationKind.None);
_writer.WriteLine($"{objIdentifier}[{parsedKeyExpr}] = {Identifier.element};");
}
......
......@@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using Microsoft.Extensions.Configuration;
......@@ -664,5 +666,59 @@ public struct StructWithParameterlessAndParameterizedCtor
public int MyInt { get; }
}
[TypeConverter(typeof(GeolocationTypeConverter))]
public struct Geolocation : IEquatable<Geolocation>, IParsable<Geolocation>
{
public static readonly Geolocation Zero = new(0, 0);
public Geolocation(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
public double Latitude { get; set; }
public double Longitude { get; set; }
private sealed class GeolocationTypeConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
{
if (sourceType == typeof(string) || sourceType == typeof(Geolocation))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value)
{
if (value is string s)
{
return Parse(s, culture);
}
else if (value is Geolocation geolocation)
{
return geolocation;
}
return base.ConvertFrom(context, culture, value);
}
}
public bool Equals(Geolocation other) => Latitude == other.Latitude && Longitude == other.Longitude;
public static Geolocation Parse(string s, IFormatProvider? provider) => throw new NotImplementedException();
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out Geolocation result) => throw new NotImplementedException();
}
public class GeolocationWrapper
{
public Geolocation Location { get; set; }
}
}
}
......@@ -1900,5 +1900,70 @@ public void AllowsCaseInsensitiveMatch()
GenericOptionsWithParamCtor<string> obj2 = configuration.Get<GenericOptionsWithParamCtor<string>>();
Assert.Equal("MyString", obj2.Value);
}
[Fact]
public void ObjWith_IParsableT_And_TypeConverter()
{
var configuration = TestHelpers.GetConfigurationFromJsonString("""
{
"Location":
{
"Latitude": 3,
"Longitude": 4,
}
}
""");
// Neither IParsableT or TypeConverter impl are honored (https://github.com/dotnet/runtime/issues/83599).
GeolocationWrapper obj = configuration.Get<GeolocationWrapper>();
ValidateGeolocation(obj.Location);
configuration = TestHelpers.GetConfigurationFromJsonString(""" { "Geolocation": "3, 4", } """);
obj = configuration.Get<GeolocationWrapper>();
Assert.Equal(Geolocation.Zero, obj.Location);
}
[Fact]
public void ComplexObj_As_Dictionary_Element()
{
var configuration = TestHelpers.GetConfigurationFromJsonString("""
{
"First":
{
"Latitude": 3,
"Longitude": 4,
}
}
""");
Geolocation obj = configuration.Get<IDictionary<string, Geolocation>>()["First"];
ValidateGeolocation(obj);
obj = configuration.Get<IReadOnlyDictionary<string, Geolocation>>()["First"];
ValidateGeolocation(obj);
}
[Fact]
public void ComplexObj_As_Enumerable_Element()
{
var configuration = TestHelpers.GetConfigurationFromJsonString("""{ "Enumerable": [{ "Latitude": 3, "Longitude": 4 }] }""")
.GetSection("Enumerable");
Geolocation obj = configuration.Get<IList<Geolocation>>()[0];
ValidateGeolocation(obj);
obj = configuration.Get<Geolocation[]>()[0];
ValidateGeolocation(obj);
obj = configuration.Get<IReadOnlyList<Geolocation>>()[0];
ValidateGeolocation(obj);
}
private void ValidateGeolocation(Geolocation location)
{
Assert.Equal(3, location.Latitude);
Assert.Equal(4, location.Longitude);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册