IUnionType
IUnionType is interface for union type features.
/// <summary>Union type.</summary>
/// <remarks>Valid type has <see cref="Tags"/> assigned.</remarks>
public interface IUnionType : IDataType, ICyclical
{
/// <summary>Tag components.</summary>
IDataTypeBase[] Tags { get; set; }
}
UnionType is the default implementation.
IUnionType unionType = new UnionType
{
Name = Identities.CreateName("Message").SetReadOnly(),
Annotations = { },
Description = "",
Nullable = true,
Referable = true,
Tags = new IDataTypeBase[]
{
new RecordType("Result")
.AddField(new FieldType("Value", DataTypes.String))
.SetReadOnly(),
new RecordType("Error")
.AddField(new FieldType("ErrorCode", DataTypes.Int))
.AddField(new FieldType("Message", DataTypes.String))
.SetReadOnly()
}
}.SetReadOnly();
Message : IUnionType ├── Tags[0] = Result : IRecordType │ └── Fields[0] = Value : IFieldType │ └── Value = string : IStringType │ └── Element = char : IIntegerType └── Tags[1] = Error : IRecordType ├── Fields[0] = ErrorCode : IFieldType │ └── Value = int : IIntegerType └── Fields[1] = Message : IFieldType └── Value = string : IStringType
UnionTypeRequest is request for an union type when sub-requests are needed.
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// Create request
UnionTypeRequest request = new UnionTypeRequest
{
Name = Identities.CreateName("Message"),
Annotations = { },
Description = "",
Nullable = null,
Referable = null,
Tags = new object[] {
new RecordTypeRequest
{
Name = Identities.CreateName("Result"),
Fields = new object[] {
new FieldTypeRequest
{
Name = Identities.CreateName("Value"),
Value = DataTypes.String
},
}
},
new RecordTypeRequest
{
Name = Identities.CreateName("Error"),
Fields = new object[] {
new FieldTypeRequest
{
Name = Identities.CreateName("ErrorCode"),
Value = DataTypes.Int
},
new FieldTypeRequest
{
Name = Identities.CreateName("Message"),
Value = DataTypes.String
},
}
},
}
};
// Query
IUnionType datatype = service.GetRequired<UnionTypeRequest, IUnionType>(request);
Message : IUnionType ├── Tags[0] = Result : IRecordType └── Tags[1] = Result : IRecordType └── Fields[0] = Value : IFieldType └── Value = string : IStringType └── Element = char : IIntegerType
[Union(tagTypes)] attribute is a way to define an union type for a referable type.
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// Create request
DataTypeRequest<IUnionType> request = new(typeof(IResponse));
// Query
IUnionType datatype = service.GetRequired<DataTypeRequest<IUnionType>, IUnionType>(request);
[Union(typeof(Result), typeof(Error))]
public interface IResponse
{
public sealed class Result : IResponse
{
public string? Value;
}
public sealed class Error : IResponse
{
public int ErrorCode;
public string? Message;
}
}
uniontype+IResponse, docs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null : IUnionType ├── Tags[0] = IResponse+Result, docs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null : IRecordType │ └── Fields[0] = Value : IFieldType │ └── Value = string : IStringType │ └── Element = char : IIntegerType └── Tags[1] = IResponse+Error, docs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null : IRecordType ├── Fields[0] = ErrorCode : IFieldType │ └── Value = int : IIntegerType └── Fields[1] = Message : IFieldType └── Value = string : IStringType
[StructLayout(LayoutKind.Explicit)] is another way to formulate an union type. Each field must have [FieldOffset(X)] attribute.
The first field at [FieldOffset(0)] indicates tag type. Its length and name can be anything. All other fields must have non zero offset.
// Create request
DataTypeRequest<IUnionType> request = new(typeof(MyUnion));
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)] public byte Tag;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
}
uniontype+MyUnion, docs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null : IUnionType ├── Tags[0] = uint : IIntegerType ├── Tags[1] = ushort : IIntegerType └── Tags[2] = bool : IIntegerType
enum is also suitable tag type.
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)] public UnionKind Kind;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
public enum UnionKind : byte { Int, Short, Bool }
}
uniontype+MyUnion, docs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null : IUnionType ├── Tags[0] = uint : IIntegerType ├── Tags[1] = ushort : IIntegerType └── Tags[2] = bool : IIntegerType
Full Example
Full example
using System.Runtime.InteropServices;
using Avalanche.DataType;
using Avalanche.Identity;
using Avalanche.Service;
using Avalanche.Utilities;
using static System.Console;
public class uniontype
{
public static void Run()
{
{
// <01>
IUnionType unionType = new UnionType
{
Name = Identities.CreateName("Message").SetReadOnly(),
Annotations = { },
Description = "",
Nullable = true,
Referable = true,
Tags = new IDataTypeBase[]
{
new RecordType("Result")
.AddField(new FieldType("Value", DataTypes.String))
.SetReadOnly(),
new RecordType("Error")
.AddField(new FieldType("ErrorCode", DataTypes.Int))
.AddField(new FieldType("Message", DataTypes.String))
.SetReadOnly()
}
}.SetReadOnly();
// </01>
// Print
WriteLine(unionType.PrintTree());
}
{
// <03>
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// Create request
UnionTypeRequest request = new UnionTypeRequest
{
Name = Identities.CreateName("Message"),
Annotations = { },
Description = "",
Nullable = null,
Referable = null,
Tags = new object[] {
new RecordTypeRequest
{
Name = Identities.CreateName("Result"),
Fields = new object[] {
new FieldTypeRequest
{
Name = Identities.CreateName("Value"),
Value = DataTypes.String
},
}
},
new RecordTypeRequest
{
Name = Identities.CreateName("Error"),
Fields = new object[] {
new FieldTypeRequest
{
Name = Identities.CreateName("ErrorCode"),
Value = DataTypes.Int
},
new FieldTypeRequest
{
Name = Identities.CreateName("Message"),
Value = DataTypes.String
},
}
},
}
};
// Query
IUnionType datatype = service.GetRequired<UnionTypeRequest, IUnionType>(request);
// </03>
// Print
WriteLine(datatype.PrintTree());
}
{
// <04>
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// Create request
DataTypeRequest<IUnionType> request = new(typeof(IResponse));
// Query
IUnionType datatype = service.GetRequired<DataTypeRequest<IUnionType>, IUnionType>(request);
// </04>
// Print
WriteLine(datatype.PrintTree());
}
{
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// <05>
// Create request
DataTypeRequest<IUnionType> request = new(typeof(MyUnion));
// </05>
// Query
IUnionType datatype = service.GetRequired<DataTypeRequest<IUnionType>, IUnionType>(request);
// Print
WriteLine(datatype.PrintTree());
}
{
// Create service
IService service = Services.Create((ServiceHandlers.Instance, DataTypeHandlers.Instance));
// <06>
// Create request
DataTypeRequest<IUnionType> request = new(typeof(MyUnion));
// </06>
// Query
IUnionType datatype = service.GetRequired<DataTypeRequest<IUnionType>, IUnionType>(request);
// Print
WriteLine(datatype.PrintTree());
}
}
// <100>
[Union(typeof(Result), typeof(Error))]
public interface IResponse
{
public sealed class Result : IResponse
{
public string? Value;
}
public sealed class Error : IResponse
{
public int ErrorCode;
public string? Message;
}
}
// </100>
// <101>
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)] public byte Tag;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
}
// </101>
static class _102
{
// <102>
[StructLayout(LayoutKind.Explicit)]
public struct MyUnion
{
[FieldOffset(0)] public UnionKind Kind;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
public enum UnionKind : byte { Int, Short, Bool }
}
// </102>
}
static class _103
{
// <103>
[StructLayout(LayoutKind.Explicit)]
public sealed class MyUnion
{
[FieldOffset(0)] public byte Tag;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
}
// </103>
}
static class _104
{
// <104>
[StructLayout(LayoutKind.Explicit)]
public sealed class MyUnion
{
[FieldOffset(0)] public UnionKind Kind;
[FieldOffset(1)] public uint Int;
[FieldOffset(1)] public ushort Short;
[FieldOffset(1)] public bool Bool;
public enum UnionKind : byte { Int, Short, Bool }
}
// </104>
}
}