Skip to content

Repository files navigation

Union struct for C#

This package provides UnionAttribute, which can be used to generate a container struct that can hold one of several specified struct types. The generated struct can also implement specified in ExposeAttribute interfaces. Key Features:

  • UnionAttribute: Specifies that the container struct can hold only one of the specified struct types at a time.
  • ExposeAttribute: Specifies that the container struct should implement the specified interfaces, delegating the implementation to the currently held struct.

Usage

Defining the Container Struct

Define the container struct using the UnionAttribute and ExposeAttribute attributes:

usingAppegy.Union.Cells.Variants;namespaceAppegy.Union.Cells{[Union(typeof(VoidCell),typeof(EmptyCell),typeof(RegularCell))][Expose(typeof(IPuzzleCell),typeof(IMatchableCell),typeof(IMovableCell))]publicpartialstructPuzzleCell{}}

Defining the Structs and Interface

Define the structs and the interface that the container struct will implement:

namespaceAppegy.Union.Cells{publicinterfaceIPuzzleCell{publicshortId{get;}}publicinterfaceIMovableCell{publicboolMovable{get;}}publicinterfaceIMatchableCell{publicboolMatchable{get;}}}namespaceAppegy.Union.Cells.Variants{publicstructVoidCell:IPuzzleCell,IMovableCell,IMatchableCell{publicshortId=>-2;publicboolMovable=>false;publicboolMatchable=>false;}publicstructEmptyCell:IPuzzleCell,IMovableCell,IMatchableCell{publicshortId=>-1;publicboolMovable=>false;publicboolMatchable=>false;}publicstructRegularCell:IPuzzleCell,IMovableCell,IMatchableCell{publicshortId{get;set;}publicboolMovable=>true;publicboolMatchable=>true;publicRegularCell(shortid){Id=id;}}}

That is it. Generator will generate all necessary code.

Using the Generated PuzzleCell Struct

Creating an Array of PuzzleCell and Adding Different Cell Types

// Create an array of PuzzleCellPuzzleCell[]puzzleCells=newPuzzleCell[3];// Add different cell types to the arraypuzzleCells[0]=newVoidCell();puzzleCells[1]=newEmptyCell();puzzleCells[2]=newRegularCell(42);// Print information about the cellsforeach(varcellinpuzzleCells){Debug.Log($"Type: {cell.Type}, Id: {cell.Id}, Movable: {cell.Movable}, Matchable: {cell.Matchable}");}

Using switch to Check the Cell Type

foreach(varcellinpuzzleCells){switch(cell.Type){casePuzzleCell.Kind.VoidCell:Debug.Log("This is a VoidCell");break;casePuzzleCell.Kind.EmptyCell:Debug.Log("This is an EmptyCell");break;casePuzzleCell.Kind.RegularCell:Debug.Log("This is a RegularCell with Id: "+cell.Id);break;default:thrownewArgumentOutOfRangeException();}}

Using Implicit Conversion Operators

// Implicit conversion from VoidCell to PuzzleCellPuzzleCellvoidCell=newVoidCell();// Implicit conversion from PuzzleCell back to VoidCellVoidCellextractedVoidCell=voidCell;

Working with Interfaces

// Create a RegularCellPuzzleCellregularCell=newRegularCell(42);// Use the IPuzzleCell interfaceIPuzzleCellpuzzleCellInterface=regularCell;Debug.Log($"IPuzzleCell Id: {puzzleCellInterface.Id}");// Use the IMovableCell interfaceIMovableCellmovableCellInterface=regularCell;Debug.Log($"IMovableCell Movable: {movableCellInterface.Movable}");// Use the IMatchableCell interfaceIMatchableCellmatchableCellInterface=regularCell;Debug.Log($"IMatchableCell Matchable: {matchableCellInterface.Matchable}");Debug.Log($"Extracted VoidCell Id: {extractedVoidCell.Id}");

Generated Code for UnionAttribute

// <auto-generated/>usingSystem;usingSystem.Runtime.InteropServices;usingAppegy.Union.Cells.Variants;namespaceAppegy.Union.Cells{[StructLayout(LayoutKind.Explicit,Pack=1)]partialstructPuzzleCell:IEquatable<PuzzleCell>,IEquatable<VoidCell>,IEquatable<EmptyCell>,IEquatable<RegularCell>{[Serializable]publicenumKind:byte{VoidCell,EmptyCell,RegularCell,}[FieldOffset(0)]privateKind_type;[FieldOffset(1)]privateVoidCell_voidCell;[FieldOffset(1)]privateEmptyCell_emptyCell;[FieldOffset(1)]privateRegularCell_regularCell;publicKindType=>_type;publicVoidCellVoidCell{get=>Type!=Kind.VoidCell?thrownewException($"Can't get VoidCell because current type is '{Type}'."):_voidCell;set{_type=Kind.VoidCell;_voidCell=value;}}publicEmptyCellEmptyCell{get=>Type!=Kind.EmptyCell?thrownewException($"Can't get EmptyCell because current type is '{Type}'."):_emptyCell;set{_type=Kind.EmptyCell;_emptyCell=value;}}publicRegularCellRegularCell{get=>Type!=Kind.RegularCell?thrownewException($"Can't get RegularCell because current type is '{Type}'."):_regularCell;set{_type=Kind.RegularCell;_regularCell=value;}}publicPuzzleCell(VoidCellvalue){_type=Kind.VoidCell;_emptyCell=default;_regularCell=default;_voidCell=value;}publicPuzzleCell(EmptyCellvalue){_type=Kind.EmptyCell;_voidCell=default;_regularCell=default;_emptyCell=value;}publicPuzzleCell(RegularCellvalue){_type=Kind.RegularCell;_voidCell=default;_emptyCell=default;_regularCell=value;}publicoverridestringToString()=>_typeswitch{Kind.VoidCell=>_voidCell.ToString(),Kind.EmptyCell=>_emptyCell.ToString(),Kind.RegularCell=>_regularCell.ToString(),
_ =>thrownewInvalidOperationException($"Unknown type of union: {_type}")};publicoverrideintGetHashCode()=>_typeswitch{Kind.VoidCell=>_voidCell.GetHashCode(),Kind.EmptyCell=>_emptyCell.GetHashCode(),Kind.RegularCell=>_regularCell.GetHashCode(),
_ =>thrownewInvalidOperationException($"Unknown type of union: {_type}")};publicoverrideboolEquals(objectboxed)=>boxedswitch{PuzzleCellother=>Equals(other),VoidCellother=>Equals(other),EmptyCellother=>Equals(other),RegularCellother=>Equals(other),
_ =>thrownewInvalidOperationException($"Unknown type of union: {_type}")};publicboolEquals(PuzzleCellother)=>_type==other.Type&&_typeswitch{Kind.VoidCell=>_voidCell.Equals(other.VoidCell),Kind.EmptyCell=>_emptyCell.Equals(other.EmptyCell),Kind.RegularCell=>_regularCell.Equals(other.RegularCell),
_ =>thrownewInvalidOperationException($"Unknown type of union: {_type}")};publicboolEquals(VoidCellother)=>_type==Kind.VoidCell&&_voidCell.Equals(other);publicboolEquals(EmptyCellother)=>_type==Kind.EmptyCell&&_emptyCell.Equals(other);publicboolEquals(RegularCellother)=>_type==Kind.RegularCell&&_regularCell.Equals(other);publicstaticimplicitoperatorVoidCell(PuzzleCellother)=>other.VoidCell;publicstaticimplicitoperatorPuzzleCell(VoidCellother)=>newPuzzleCell(other);publicstaticimplicitoperatorEmptyCell(PuzzleCellother)=>other.EmptyCell;publicstaticimplicitoperatorPuzzleCell(EmptyCellother)=>newPuzzleCell(other);publicstaticimplicitoperatorRegularCell(PuzzleCellother)=>other.RegularCell;publicstaticimplicitoperatorPuzzleCell(RegularCellother)=>newPuzzleCell(other);publicstaticbooloperator==(PuzzleCella,PuzzleCellb)=>a.Equals(b);publicstaticbooloperator!=(PuzzleCella,PuzzleCellb)=>!a.Equals(b);publicstaticbooloperator==(PuzzleCella,VoidCellb)=>a.Equals(b);publicstaticbooloperator!=(PuzzleCella,VoidCellb)=>!a.Equals(b);publicstaticbooloperator==(PuzzleCella,EmptyCellb)=>a.Equals(b);publicstaticbooloperator!=(PuzzleCella,EmptyCellb)=>!a.Equals(b);publicstaticbooloperator==(PuzzleCella,RegularCellb)=>a.Equals(b);publicstaticbooloperator!=(PuzzleCella,RegularCellb)=>!a.Equals(b);}}

Generated Code for ExposeAttribute

// <auto-generated/>usingSystem;usingSystem.Runtime.InteropServices;usingAppegy.Union.Cells.Variants;usingAppegy.Union.Cells;namespaceAppegy.Union.Cells{partialstructPuzzleCell:IPuzzleCell,IMatchableCell,IMovableCell{
#region Implement IPuzzleCell
publicshortId{get{switch(_type){caseKind.VoidCell:return_voidCell.Id;caseKind.EmptyCell:return_emptyCell.Id;caseKind.RegularCell:return_regularCell.Id;default:thrownewInvalidOperationException($"Unknown type of union: {_type}");}}}
#endregion Implement IPuzzleCell
#region Implement IMatchableCell
publicboolMatchable{get{switch(_type){caseKind.VoidCell:return_voidCell.Matchable;caseKind.EmptyCell:return_emptyCell.Matchable;caseKind.RegularCell:return_regularCell.Matchable;default:thrownewInvalidOperationException($"Unknown type of union: {_type}");}}}
#endregion Implement IMatchableCell
#region Implement IMovableCell
publicboolMovable{get{switch(_type){caseKind.VoidCell:return_voidCell.Movable;caseKind.EmptyCell:return_emptyCell.Movable;caseKind.RegularCell:return_regularCell.Movable;default:thrownewInvalidOperationException($"Unknown type of union: {_type}");}}}
#endregion Implement IMovableCell
}}

About

No description, website, or topics provided.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages