efl-mono: Add extra constructors to Eina.Value

Summary:
new Eina.Value(0) is a special case. The 0 is silently converted
to an enum (Eina.ValueType) and therefore the call is ambiguous
with the 0 being first converted to an Eina.Value via the implicit
conversion operator (calling the Eina.Value deep copy constructor).
Adding constructors for all supported types solves the problem because
they have higher priority. Also, they avoid one deep copy of the
Eina.Value.

Includes test case to catch this problem in the future. This was discovered
in the tutorials, where new Eina.Value(0) is being used.

Test Plan:
The src/efl_reference_core_event.exe example from the examples repo was
not compiling before, and now it is.
make check and make examples still work as expected.

Reviewers: lauromoura

Reviewed By: lauromoura

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D7598
This commit is contained in:
Xavi Artigas 2019-01-11 14:28:38 +01:00
parent 3ddd577fb0
commit 48b303eeb5
2 changed files with 85 additions and 1 deletions

View File

@ -792,6 +792,83 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
this.Ownership = Ownership.Managed;
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(byte x) : this(ValueType.Byte)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(sbyte x) : this(ValueType.SByte)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(short x) : this(ValueType.Short)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(ushort x) : this(ValueType.UShort)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(int x) : this(ValueType.Int32)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(uint x) : this(ValueType.UInt32)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(long x) : this(ValueType.Long)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(ulong x) : this(ValueType.ULong)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(float x) : this(ValueType.Float)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(double x) : this(ValueType.Double)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Type-specific constructor, for convenience.</summary>
public Value(string x) : this(ValueType.String)
{
if (!Set(x))
throw new InvalidOperationException("Couldn't set value.");
}
/// <summary>Implicit conversion from managed value to native struct representation.</summary>
public static implicit operator ValueNative(Value v)
{

View File

@ -151,7 +151,14 @@ public static class TestEinaValueEolian {
Test.AssertEquals(expected, received);
Test.AssertEquals(Eina.ValueType.Double, received.GetValueType());
// Check for 0
// This is a special value, since C# can silently convert it to an enum
// leading to collisions with Eina.ValueType
expected = new Eina.Value(0);
obj.SetValue(0);
obj.OutValue(out received);
Test.AssertEquals(expected, received);
Test.AssertEquals(Eina.ValueType.Int32, received.GetValueType());
}
}
#pragma warning restore 1591