[c#] Fix default value for aliased bool/wstr field
The default value of aliased bool and wstring fields was being computed incorrectly. We were attempting to cast the aliased C# type (e.g., DateTime) to the field type instead of using the field's natural default value (false/empty). Fixes https://github.com/Microsoft/bond/issues/300 Closes https://github.com/Microsoft/bond/pull/301
This commit is contained in:
Родитель
b462c03f67
Коммит
6c11df8eb7
|
@ -13,6 +13,13 @@ different versioning scheme, following the Haskell community's
|
|||
|
||||
## Unreleased ##
|
||||
|
||||
* `gbc` & compiler library: TBD (bug fix bump needed)
|
||||
* IDL core version: TBD
|
||||
* IDL comm version: TBD
|
||||
* C++ version: TBD (minor bump needed [Boost dependencies changed])
|
||||
* C# NuGet version: TBD (minor bump needed)
|
||||
* C# Comm NuGet version: TBD (minor bump needed [dependencies changed])
|
||||
|
||||
### C++ ###
|
||||
|
||||
* Fixed compatibility with RapidJSON v1.1.0.
|
||||
|
@ -27,6 +34,8 @@ different versioning scheme, following the Haskell community's
|
|||
|
||||
* Added controls to cap pre-allocation during deserialization of containers
|
||||
and blobs.
|
||||
* Fixed computation of default value for aliased bool and wstring fields.
|
||||
[Issue #300](https://github.com/Microsoft/bond/issue/300)
|
||||
|
||||
### C# Comm ###
|
||||
|
||||
|
|
|
@ -186,12 +186,18 @@ namespace Bond
|
|||
}
|
||||
else
|
||||
{
|
||||
var alias = defaultValue.GetType() != schemaField.GetSchemaType();
|
||||
Type defaultValueType = defaultValue.GetType();
|
||||
Type schemaFieldType = schemaField.GetSchemaType();
|
||||
|
||||
if (schemaFieldType == typeof (Tag.wstring))
|
||||
schemaFieldType = typeof (string);
|
||||
|
||||
bool alias = defaultValueType != schemaFieldType;
|
||||
|
||||
switch (schemaField.GetSchemaType().GetBondDataType())
|
||||
{
|
||||
case BondDataType.BT_BOOL:
|
||||
variant.uint_value = (bool) defaultValue ? 1ul : 0ul;
|
||||
variant.uint_value = alias ? 0ul : ((bool) defaultValue ? 1ul : 0ul);
|
||||
break;
|
||||
|
||||
case BondDataType.BT_UINT8:
|
||||
|
@ -221,7 +227,7 @@ namespace Bond
|
|||
break;
|
||||
|
||||
case BondDataType.BT_WSTRING:
|
||||
variant.wstring_value = (string)defaultValue;
|
||||
variant.wstring_value = alias ? string.Empty : (string)defaultValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Bond;
|
||||
using NUnit.Framework;
|
||||
|
@ -107,6 +108,130 @@
|
|||
{
|
||||
return new ArraySegment<byte>(value);
|
||||
}
|
||||
|
||||
#region Box<T> for basic types
|
||||
|
||||
public static bool Convert(Box<bool> value, bool unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<bool> Convert(bool value, Box<bool> unused)
|
||||
{
|
||||
return new Box<bool>(value);
|
||||
}
|
||||
|
||||
public static SByte Convert(Box<SByte> value, SByte unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<SByte> Convert(SByte value, Box<SByte> unused)
|
||||
{
|
||||
return new Box<SByte>(value);
|
||||
}
|
||||
|
||||
public static Int16 Convert(Box<Int16> value, Int16 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<Int16> Convert(Int16 value, Box<Int16> unused)
|
||||
{
|
||||
return new Box<Int16>(value);
|
||||
}
|
||||
|
||||
public static Int32 Convert(Box<Int32> value, Int32 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<Int32> Convert(Int32 value, Box<Int32> unused)
|
||||
{
|
||||
return new Box<Int32>(value);
|
||||
}
|
||||
|
||||
public static Int64 Convert(Box<Int64> value, Int64 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<Int64> Convert(Int64 value, Box<Int64> unused)
|
||||
{
|
||||
return new Box<Int64>(value);
|
||||
}
|
||||
|
||||
public static Byte Convert(Box<Byte> value, Byte unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<Byte> Convert(Byte value, Box<Byte> unused)
|
||||
{
|
||||
return new Box<Byte>(value);
|
||||
}
|
||||
|
||||
public static UInt16 Convert(Box<UInt16> value, UInt16 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<UInt16> Convert(UInt16 value, Box<UInt16> unused)
|
||||
{
|
||||
return new Box<UInt16>(value);
|
||||
}
|
||||
|
||||
public static UInt32 Convert(Box<UInt32> value, UInt32 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<UInt32> Convert(UInt32 value, Box<UInt32> unused)
|
||||
{
|
||||
return new Box<UInt32>(value);
|
||||
}
|
||||
|
||||
public static UInt64 Convert(Box<UInt64> value, UInt64 unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<UInt64> Convert(UInt64 value, Box<UInt64> unused)
|
||||
{
|
||||
return new Box<UInt64>(value);
|
||||
}
|
||||
|
||||
public static float Convert(Box<float> value, float unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<float> Convert(float value, Box<float> unused)
|
||||
{
|
||||
return new Box<float>(value);
|
||||
}
|
||||
|
||||
public static double Convert(Box<double> value, double unused)
|
||||
{
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static Box<double> Convert(double value, Box<double> unused)
|
||||
{
|
||||
return new Box<double>(value);
|
||||
}
|
||||
|
||||
public static string Convert(Box<string> value, string unused)
|
||||
{
|
||||
return value.Value ?? string.Empty;
|
||||
}
|
||||
|
||||
public static Box<string> Convert(string value, Box<string> unused)
|
||||
{
|
||||
return new Box<string>(string.IsNullOrEmpty(value) ? null : value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
[TestFixture]
|
||||
|
@ -125,7 +250,7 @@
|
|||
|
||||
TestTypeAliases(from);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void AliasContainer()
|
||||
{
|
||||
|
@ -260,6 +385,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AliasesWithConverter()
|
||||
{
|
||||
var converted = new ConvertedTypes();
|
||||
TestTypeAliases(converted);
|
||||
|
||||
converted = new ConvertedTypes
|
||||
{
|
||||
c_bool = true,
|
||||
c_int8 = -8,
|
||||
c_int16 = -16,
|
||||
c_int32 = -32,
|
||||
c_int64 = -64,
|
||||
c_uint8 = 8,
|
||||
c_uint16 = 16,
|
||||
c_uint32 = 32,
|
||||
c_uint64 = 64,
|
||||
c_float = 4.0f,
|
||||
c_double = 8.0,
|
||||
c_string = "string",
|
||||
c_wstring = "wstring"
|
||||
};
|
||||
TestTypeAliases(converted);
|
||||
}
|
||||
|
||||
static BlobAlias InitBlobAlias()
|
||||
{
|
||||
return new BlobAlias
|
||||
|
@ -284,6 +434,94 @@
|
|||
}
|
||||
}
|
||||
|
||||
public struct Box<T>
|
||||
{
|
||||
public T Value;
|
||||
|
||||
public Box(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public static implicit operator Box<T>(T value)
|
||||
{
|
||||
return new Box<T>(value);
|
||||
}
|
||||
|
||||
public static bool operator ==(Box<T> left, Box<T> right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Box<T> left, Box<T> right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
// We must provide implementations of operator == and operator != to
|
||||
// use this type in our tests. However, it is a C# compiler error to
|
||||
// implement these operators without overriding Equals and GetHashCode.
|
||||
// However, the default implementation of these methods is sufficient.
|
||||
// Hence, we have these apparently useless overrides.
|
||||
//
|
||||
// The name of the ReSharper warning is not spelled correctly.
|
||||
//
|
||||
// ReSharper disable RedundantOverridenMember
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
// ReSharper restore RedundantOverridenMember
|
||||
}
|
||||
|
||||
[Bond.Schema]
|
||||
public class ConvertedTypes
|
||||
{
|
||||
[Bond.Id(0), Bond.Type(typeof(bool))]
|
||||
public Box<bool> c_bool;
|
||||
|
||||
[Bond.Id(1), Bond.Type(typeof(sbyte))]
|
||||
public Box<sbyte> c_int8;
|
||||
|
||||
[Bond.Id(2), Bond.Type(typeof(short))]
|
||||
public Box<short> c_int16;
|
||||
|
||||
[Bond.Id(3), Bond.Type(typeof(int))]
|
||||
public Box<int> c_int32;
|
||||
|
||||
[Bond.Id(4), Bond.Type(typeof(long))]
|
||||
public Box<long> c_int64;
|
||||
|
||||
[Bond.Id(5), Bond.Type(typeof(byte))]
|
||||
public Box<byte> c_uint8;
|
||||
|
||||
[Bond.Id(6), Bond.Type(typeof(ushort))]
|
||||
public Box<ushort> c_uint16;
|
||||
|
||||
[Bond.Id(7), Bond.Type(typeof(uint))]
|
||||
public Box<uint> c_uint32;
|
||||
|
||||
[Bond.Id(8), Bond.Type(typeof(ulong))]
|
||||
public Box<ulong> c_uint64;
|
||||
|
||||
[Bond.Id(9), Bond.Type(typeof(float))]
|
||||
public Box<float> c_float;
|
||||
|
||||
[Bond.Id(10), Bond.Type(typeof(double))]
|
||||
public Box<double> c_double;
|
||||
|
||||
[Bond.Id(11), Bond.Type(typeof(string))]
|
||||
public Box<string> c_string;
|
||||
|
||||
[Bond.Id(12), Bond.Type(typeof(Bond.Tag.wstring))]
|
||||
public Box<string> c_wstring;
|
||||
}
|
||||
|
||||
// An extremely simple example of a custom container implementation.
|
||||
public class SomeCustomList<T> : ICollection<T>, ICollection
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче