ObjectEnum 1.0.0-alpha
See the version list below for details.
dotnet add package ObjectEnum --version 1.0.0-alpha
NuGet\Install-Package ObjectEnum -Version 1.0.0-alpha
<PackageReference Include="ObjectEnum" Version="1.0.0-alpha" />
paket add ObjectEnum --version 1.0.0-alpha
#r "nuget: ObjectEnum, 1.0.0-alpha"
// Install ObjectEnum as a Cake Addin
#addin nuget:?package=ObjectEnum&version=1.0.0-alpha&prerelease
// Install ObjectEnum as a Cake Tool
#tool nuget:?package=ObjectEnum&version=1.0.0-alpha&prerelease
ObjectEnum
ObjectEnum is a wrapper for enums, adding a certain degree of polymorphism.
Examples
Restrict enum values to a subset
Conssider the WorkDay class:
public class WorkDay : ObjectEnum<DayOfWeek>
{
public WorkDay(DayOfWeek value)
: base(value) { }
private static readonly DayOfWeek[] Values = new[]
{
DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday,
DayOfWeek.Thursday, DayOfWeek.Friday
};
protected override IReadOnlyCollection<DayOfWeek> GetDefinedValues()
=> Values;
}
Which will produce the following results:
var sunday = new WorkDay(DayOfWeek.Sunday); //throws exception
var monday = new WorkDay(DayOfWeek.Monday); //works fine
var label = $"{monday} is day {(int)monday}." //produces: "Monday is day 1."
var mondayIsAlwaysMonday = monday == DayOfWeek.Monday; //true, sorry...
Inheritance
Conssider these classes:
public class ChillDay : ObjectEnum<DayOfWeek>
{
public ChillDay(DayOfWeek value)
: base(value) { }
private static readonly DayOfWeek[] Values = new[]
{
DayOfWeek.Saturday, DayOfWeek.Sunday
};
protected override IReadOnlyCollection<DayOfWeek> GetDefinedValues()
=> Values;
}
public class FunDay : ChillDay
{
public FunDay(DayOfWeek value)
: base(value) { }
private static readonly DayOfWeek[] Values = new[]
{
DayOfWeek.Saturday, DayOfWeek.Sunday, DayOfWeek.Friday
};
protected override IReadOnlyCollection<DayOfWeek> GetDefinedValues()
=> Values;
}
Which will produce the following results:
var sunday = new ChillDay(DayOfWeek.Sunday);
var funday = new FundDay(DayOfWeek.Sunday);
var sundayIsFunday = sunday == funday; //true
In this case the comparison will return true, because FundDay inherits ChillDay. However in the case of a Workday, this would not be the case as there is no relation between a WorkDay and a FundDay.
var friday = new WorkDay(DayOfWeek.Friday);
var funday = new FundDay(DayOfWeek.Friday);
var workFridayIsNoFunFriday = friday == funday; //false
Switch cases
You can easily use a ObjectEnum in a switch case, however you will need to cast it to the appropriate enum.
var friday = new WorkDay(DayOfWeek.Friday);
switch((DayOfWeek)friday){
case DayOfWeek.Monday:
//do something monday related
break;
/*...*/
case DayOfWeek.Friday:
//do something friday related
break;
}
Or cast it to an integer.
var friday = new WorkDay(DayOfWeek.Friday);
switch((int)friday){
case 1:
//do something monday related
break;
/*...*/
case 5:
//do something friday related
break;
}
Declaring your own ObjectEnums
//you can optionally declare an abstract base type for your implementations
public abstract class Size : ObjectEnum<Size.Value>
{
//define a single enum containing all possible values
//it can be a nested enum like it is here,
//but this is not required
public enum Value
{
Unknown = 0,
ExtraSmall = 1,
Small = 2,
Medium = 3,
Large = 4,
ExtraLarge = 5
}
protected Size(Value value)
: base(value) { }
}
public class BasicSize : Size
{
public BasicSize(Value value)
: base(value) { }
//declaring a static Values array reduces
//the overhead on creating a new array each time
//we instantiate a BasicSize object
private static readonly Value[] Values = new[]
{
Value.Unknown, Value.Small, Value.Medium, Value.Large
};
//override GetDefinedValues to restrict the possible values for BasicSize
protected override IReadOnlyCollection<Value> GetDefinedValues()
=> Values;
}
//inherit BasicSize so we can compare the values
public class ExtendedSize : BasicSize
{
public ExtendedSize(Value value)
: base(value) { }
//not the prefered way, but should work
protected override IReadOnlyCollection<Value> GetDefinedValues()
=> new[] {
Value.Unknown, Value.ExtraSmall, Value.Small, Value.Medium, Value.Large, Value.ExtraLarge
};
}
Other helpful stuff
As you may have noticed, it is easy to cast between a ObjectEnum and its underlying enum Type, as well as casting to the int representation.
Besides this, a number of helper methods are defined to help you instantiate ObjectEnums
var isFriday = WorkDay.TryParse("Friday", out var friday); //returns true, friday = new WorkDay(DayOfWeek.Friday)
var isMonday = WorkDay.TryParse("monday", ignoreCase: false, out var mondaytues); //returns true, monday = new WorkDay(DayOfWeek.Monday)
var tuesday = WorkDay.Parse<WorkDay>("tuesday"); //returns new WorkDay(DayOfWeek.Tuesday)
var wednessday = WorkDay.Create<WorkDay>(DayOfWeek.Wednessday); //returns new WorkDay(DayOfWeek.Wednessday)
You can also use the various overloads of IsDefined
to determine whether a certain value is valid for the given ObjectEnum.
Product | Versions |
---|---|
.NET | net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows |
.NET Core | netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 |
.NET Standard | netstandard2.0 netstandard2.1 |
.NET Framework | net461 net462 net463 net47 net471 net472 net48 net481 |
MonoAndroid | monoandroid |
MonoMac | monomac |
MonoTouch | monotouch |
Tizen | tizen40 tizen60 |
Xamarin.iOS | xamarinios |
Xamarin.Mac | xamarinmac |
Xamarin.TVOS | xamarintvos |
Xamarin.WatchOS | xamarinwatchos |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.0 | 434 | 11/15/2019 |
1.0.0-alpha1 | 306 | 10/15/2019 |
1.0.0-alpha | 307 | 10/15/2019 |
This first version was hacked together in a few hours because I couldn't quite find an elegant solution for polymorphic enums on the net. Things got out of hand, and I ended up with a pretty feature complete package, so here you go.
Please keep in mind that this solution has not been field tested, and quite frankly, I was a bit drunk when I wrote it. Please refer to the GitHub repo for documentation as well as any issues, comments or requests.