I have a few methods like the following
public static string RequestEntry (string name)
{
if (name == "John" || name == "Bob" || name == "Ken")
return $"Hello {name}, you may enter";
return $"Get out of here {name}, no one like you!";
}
public static string Kiddify (string name)
{
if (name == "John" || name == "Bob" || name == "Ken")
return $"{name}{name[^1]}y";
return $"Get out of here {name}, no one like you!";
}
Note: These are only meant to demonstrate a concept and not the purposes of my real methods. My real methods have their own isolated functionality.)
My issues with this is:
I am a very bad typer/speller and will most likely mistype the string that pass into this method, which could introduce bugs.
I don't want there to be a default case, because I have specific input string I want to work with.
Programming is a hobby. I will sometimes go weeks without having time to code and remembering the valid strings I can pass is highly unlikely.
So, I thought to use an enum
public enum Name{
John,
Bob,
Ken
}
and implement the methods as follows
public static string RequestEntry (Name name)
{
string sName = name switch
{
Name.John => "John",
Name.Bob => "Bob",
Name.Ken => "Ken",
_ => throw new NotImplementedException()
};
return $"Hello {sName}, you may enter";
}
public static string Kiddify (Name name)
{
return name switch
{
Name.John => "Johnny",
Name.Bob => "Bobby",
Name.Ken => "Kenny",
_ => throw new NotImplementedException()
};
}
I feel like this would be pretty common practice, and it solves all my above issues. Now my issue is that modifying Names will mean I also have to modify my class methods to deal with the changes.
And finally, we get to the question. Is there another way I do this?
I considered using reflection and attributes to assign string values to the different names in the enum, but I would have to assign a different string attribute for each use case. I don't like that idea and don't like using reflection if at all possible.
Why not organize names into a collection? For instance
private static readonly HashSet<string> s_Names = new() {
"John", "Bob", "Ken"
};
public static string RequestEntry (string name) =>
s_Names.Contains(name)
? $"Hello {name}, you may enter"
: $"Get out of here {name}, no one like you!";
You can use the Enum.ToString method to get the string "John" from an enum. For example:
Names.John.ToString()
You can use your Kiddify method on this string afterwards.
(The opposite is Enum.TryParse which will get the enum value from a string. )
Thank you for your inputs, but (as is sometimes the case) about an hour after I posted the question, I thought of a solution that would work for me.
using System;
public class Names
{
public string adultName;
public string kidName;
public static Names John = new Names
{
adultName = "John",
kidName = "Johnny"
};
public static Names Bob = new Names
{
adultName = "Bob",
kidName = "Bobby"
};
public static Names Ken = new Names
{
adultName = "Ken",
kidName = "Kenny"
};
}
public class Program
{
public static void Main()
{
Console.WriteLine(RequestEntry(Names.John));
Console.WriteLine(Kiddify(Names.Bob));
}
public static string RequestEntry (Names name)
{
return $"Hello {name.adultName}, you may enter";
}
public static string Kiddify (Names name)
{
return name.kidName;
}
}
What do you all think?
Related
I have a class with some fields.
public abstract class RegisteredUser : Transformable //implements interface
{
protected int id;
protected bool active;
protected string name;
protected string lastName;
protected string email;
protected string username;
protected string password;
protected int institution;
//OTHER STUFF FROM THIS CLASS GO HERE..`
}
Assistant : RegisteredUser
{
}
Once I load all data from .txt file, I'll have a static dictionary like this:
public static Dictionary<int, Transformable> assistants = null; //this will be filed with objects and their id's
Now, my assignment is to achieve functionality of search for this console app. Since, all of sub classes will have fields from abstract class, user of this app should have a choice to search for any object Assistant, Professor or Administrator by any of its fields.
I would like to achieve this by using LINQ/lambdas. My idea is to create some generic method which will accept a selector (or some lambda expression ), based on whatever field is being searched for.
I am completely new to LINQ and C# and generally to programming, so I hope that I'm not talking nonsense here.
public static List<RegisteredUser> search(Dictionary<int, Transformable> map,
Func<bool,RegisteredUser> selector,
Transformable userType)
{
if (userType is Assistant)
{
List<RegisteredUser> list = map.Select(item => (Assistant) item.Value)
.ToList()
.Select(selector)
.ToList();
}
//other if/else statements
return list;
}
Of course, lines in Visual Studio are red :) Basically, I want to be be able send something like
user => user.Name.Contains("some string which will be entered by the end user") to generic function.
You don't really need to write a separate function to do what you want to achieve, it can all be done with Linq directly:
var users = new Dictionary<int, Transformable>
{
{0, new Assistant { Name = "Joe" }},
{1, new Professor { Name = "John" }},
{2, new Assistant { Name = "Jane" }}
};
var assistants = users.Values.OfType<Assistant>().Where(a => a.Name == "Jane");
assistants is an IEnumerable<Assistant> with Name equal to "Jane" and will contain only 1 entry from the above dictionary. You could add a ToList() to the end of that to create list alternatively
You can then add whatever predicate you want:
var assistants = users.Values.OfType<Assistant>().Where(a => a.Name == "Jane" && a.LastName == "Smith" && a.Active);
You could wrap the above in a function but what you'll end up with won't be much shorter than the above.
As an extension method it would be like this:
public static class Extensions
{
public static IEnumerable<T> Find<T>(this IEnumerable<Transformable> list, Func<T,bool> predicate) where T :Transformable
{
return list.OfType<T>().Where(predicate.Invoke);
}
}
making the call slightly shorter:
var assistants = users.Values.Find<Assistant>(a => a.Name == "Jane");
This is an example of the fluent API pattern so you can use it in a Linq chain like any other Linq function.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding the Variable Name passed to a Function in C#
The class below contains the field city.
I need to dynamically determine the field's name as it is typed in the class declaration
i.e. I need to get the string "city" from an instance of the object city.
I have tried to do this by examining its Type in DoSomething() but can't find it when examining the contents of the Type in the debugger.
Is it possible?
public class Person
{
public string city = "New York";
public Person()
{
}
public void DoSomething()
{
Type t = city.GetType();
string field_name = t.SomeUnkownFunction();
//would return the string "city" if it existed!
}
}
Some people in their answers below have asked me why I want to do this.
Here's why.
In my real world situation, there is a custom attribute above city.
[MyCustomAttribute("param1", "param2", etc)]
public string city = "New York";
I need this attribute in other code.
To get the attribute, I use reflection.
And in the reflection code I need to type the string "city"
MyCustomAttribute attr;
Type t = typeof(Person);
foreach (FieldInfo field in t.GetFields())
{
if (field.Name == "city")
{
//do stuff when we find the field that has the attribute we need
}
}
Now this isn't type safe.
If I changed the variable "city" to "workCity" in my field declaration in Person this line would fail unless I knew to update the string
if (field.Name == "workCity")
//I have to make this change in another file for this to still work, yuk!
{
}
So I am trying to find some way to pass the string to this code without physically typing it.
Yes, I could declare it as a string constant in Person (or something like that) but that would still be typing it twice.
Phew! That was tough to explain!!
Thanks
Thanks to all who answered this * a lot*. It sent me on a new path to better understand lambda expressions. And it created a new question.
Maybe you need this. Works fine.
I found this here.
static void Main(string[] args)
{
var domain = "matrix";
Check(() => domain);
Console.ReadLine();
}
static void Check<T>(Expression<Func<T>> expr)
{
var body = ((MemberExpression)expr.Body);
Console.WriteLine("Name is: {0}", body.Member.Name);
Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value));
}
Output will be:
Name is: 'domain'
Value is: 'matrix'
I know this is old question, but I was trying to achieve the same and google sent me here. After many hours I finally found a way. I hope somebody else will find this useful.
There are actually more ways to accomplish this:
static void Main(string[] args)
{
GetName(new { var1 });
GetName2(() => var1);
GetName3(() => var1);
}
static string GetName<T>(T item) where T : class
{
return typeof(T).GetProperties()[0].Name;
}
static string GetName2<T>(Expression<Func<T>> expr)
{
return ((MemberExpression)expr.Body).Member.Name;
}
static string GetName3<T>(Func<T> expr)
{
return expr.Target.GetType().Module.ResolveField(BitConverter.ToInt32(expr.Method.GetMethodBody().GetILAsByteArray(), 2)).Name;
}
The first is fastest. The last 2 are approx 20 times slower than the 1st one.
http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
city in this case is an instance of type string. When you call .GetType() you return the actual string type, which has no knowledge at all of your particular city instance.
I'm having a hard time seeing why you can't just type "city" in the code as a string literal here, if that's what you need. Perhaps it would help if you shared what you want to use this value for and in what circumstances you will call your DoSomething() function.
At the moment, my best guess is that what you really want to do is reflect the entire Person class to get a list of the fields in that class:
public void DoSomething()
{
MemberInfo[] members = this.GetType().GetMembers();
// now you can do whatever you want with each of the members,
// including checking their .Name properties.
}
Okay, based on your edit I have some more for you.
You can find the name of fields that are decorated with your attribute at run-time like this:
Type t = typeof(Person);
foreach (MemberInfo member in t.GetMembers()
.Where(m =>
m.GetCustomAttributes(typeof(MyCustomAttribute)).Any() ) )
{
// "member" is a MemberInfo object for a Peson member that is
// decorated with your attribute
}
You can also use binding flags in the first GetMembers() call to limit it to just fields, if you want.
You mentioned "i.e. I need to get the string "city" from an instance of the object city."
Are you looking to get the field name from the value of the field.
For example:If there are 2 Person object one with city "New York" and the other with city "London", are you looking for the function to return "city". Is this what you mean by dynamic?
With your current design you will always need to compare the name of the field from the FieldInfo against a string.
What if you instead decouple this so that you hold the identifier to use for comparison purposes during reflection as part of the attribute.
Something like this:
public enum ReflectionFields
{
CITY = 0,
STATE,
ZIP,
COUNTRY
}
[AttributeUsage(AttributeTargets.Field,AllowMultiple=false)]
public class CustomFieldAttr : Attribute
{
public ReflectionFields Field { get; private set; }
public string MiscInfo { get; private set; }
public CustomFieldAttr(ReflectionFields field, string miscInfo)
{
Field = field;
MiscInfo = miscInfo;
}
}
public class Person
{
[CustomFieldAttr(ReflectionFields.CITY, "This is the primary city")]
public string _city = "New York";
public Person()
{
}
public Person(string city)
{
_city = city;
}
}
public static class AttributeReader<T> where T:class
{
public static void Read(T t)
{
//get all fields which have the "CustomFieldAttribute applied to it"
var fields = t.GetType().GetFields().Where(f => f.GetCustomAttributes(typeof(CustomFieldAttr), true).Length == 1);
foreach (var field in fields)
{
var attr = field.GetCustomAttributes(typeof(CustomFieldAttr), true).First() as CustomFieldAttr;
if (attr.Field == ReflectionFields.CITY)
{
//You have the field and you know its the City,do whatever processing you need.
Console.WriteLine(field.Name);
}
}
}
}
public class Program
{
public static void Main(string[] args)
{
PPerson p1 = new PPerson("NewYork");
PPerson p2 = new PPerson("London");
AttributeReader<PPerson>.Read(p1);
AttributeReader<PPerson>.Read(p2);
}
}
You can now freely rename _city field of Person to something else and your calling code will still work since the code using reflection is trying to identify the field using the ReflectionFields enum value set as part of initialization of the attribute set on the field.
Yes its possible !!!
Try this out...
public string DoSomething(object city)
{
return city.GetType().GetProperty("Name",typeof(string)).GetValue(city,null);
}
Two things here.
Number one, as someone above pointed out, you're getting the Type for string, not for Person. So typeof(Person).GetMembers() will get you the list of members.
Number two, and more importantly, it looks like you're misunderstanding the purpose of attributes. In general attributes are used to mark a member for specific processing or to add additional information. Here you're using the name to indicate what processing you want, and the attribute to specify parameters, which is mixing of metaphors, or something.
Abhijeet's answer is more appropriate, you mark the field as a city field, then do what you like with it. Where I disagree is that I would use different attribute classes, rather than an enumeration.
Something like:
public class MyAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Field)]
public class MyCityAttribute : MyAttribute
{
}
[AttributeUsage(AttributeTargets.Field]
public class MyNameAttribute: MyAttribute
{
}
public class Person
{
[MyCity]
public string city = "New York";
[MyCity]
public string workCity = "Chicago";
[MyName]
public string fullName = "John Doe";
public Person()
{
}
public void DoSomething()
{
Type t = typeof(Person);
FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fields)
{
MyAttribute[] attributes = field.GetCustomAttributes(typeof(MyAttribute));
if (attributes.Count > 0)
{
if (attributes[0] is MyCityAttribute)
{
//Dosomething for city
break;
}
if (attributes[0] is MyNameAttribute)
{
//Dosomething for names
break;
}
}
}
}
}
This would allow you to use different parameters for MyCity vs MyName that would make more sense in the context of processing each.
I think with your 'yuk' comment above, you hit the nail on the head. That you would have to change a string constant if you rename your variable is an indicator that you're doing something wrong.
t.GetField("city", BindingFlags.Public | BindingFlags.Instance);
or you can call GetFields() to get all fields
You need to call get type on the class Person. The iterate the fields of the class as in the answer below
This is not possible (I think it actually is but involes several hacks and using lambdas). If you want to store attributes about a Person and be able to get the name of the attribute easily, I suggest using a Dictionary<TKey, TValue> from the System.Collections.Generic namespace.
And you can always make public properties that wrap the dictionary.
public class Person
{
Dictionary<string, string> attributes = new Dictionary<string, string();
public string City
{
get { return attributes["city"]; }
set { attributes["city"] = value; }
}
public Person()
{
City = "New York";
}
}
And you can get a list of all attributes with attributes.Keys.
Have a look at this post as it looks similar to what you're trying to do:
Finding the variable name passed to a function
(especially Konrad Rudolph's answer) Another approach could be to just add "city" as one of the parameters in the attribute and fish that out later.
You are already looping through the collection of FieldInfo objects. Look for your attribute on those and when you find the FieldInfo that contains your attribute, you have the one you want. Then call .Name on it.
system.reflection.fieldinfo.attributes
I have a static class with constants. I am looking for options to create a method which takes a dictionary as an argument and enforcing the key to be one of the constants from the static class.Here is my static class with constants.
Here is what I am trying to do
And here is what I am trying to enforce
From the sound of it, an Enum would be more suited to what you're trying to do.
public enum MyConstants
{
FirstName,
LastName,
Title
}
public void CreateMe(Dictionary<MyConstants, string> propertyBag)
{
...
}
UPDATED
You could combine this with attributes to associate each enum with a specific string like so:
public enum PropertyNames
{
[Description("first_name")]
FirstName,
[Description("last_name")]
LastName,
[Description("title")]
Title
}
The value of each description attribute associated with each enum value could easily be grabbed via an extension method, like so:
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fieldInfo.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
Then in your "CreateMe"-method you can get the description and value of each dictionary entry by doing something similar to this:
void CreateMe(Dictionary<PropertyNames, string> propertyBag)
{
foreach (var propertyPair in propertyBag)
{
string propertyName = propertyPair.Key.GetDescription();
string propertyValue = propertyPair.Value;
}
}
Even though this has been already answered, there is another approach, like so:
public class MyOwnEnum
{
public string Value { get; private set; }
private MyOwnEnum(string value)
{
Value = value;
}
public static readonly MyOwnEnum FirstName = new MyOwnEnum("Firstname");
public static readonly MyOwnEnum LastName = new MyOwnEnum("LastName");
}
It behaves same way like Enum and can be used in your code with same syntax. I cannot give credit to whoever came up with it, but I believe I came upon it when searching for Enums with multiple values.
With strings you can't enforce fact that keys come from limited set of vialues compile time.
Use enum or custom class (possibly with implicit conversion to string) instead.
I have a Class with the following:
public class TestClass {
string Account1 {get;set;}
string Account2 {get;set;}
string Account3 {get;set;}
}
What I would like is to be able to have a method that is similar to the following:
public TestClass[] GetTestClass(string value, string AccountName)
where i can pass in a value say "John" and the AccountName would be "Account1"
and it will go through a list of TestClass and return an array or list of TestClass objects where there exists a value "John" in the Property "Account1"
Is there a better method of doing this or any thoughts would help.
Note: This is a model based of a SQL Table
You can use the reflection to get what you want, Your method will look like this,
public List<TestClass> GetTestClass(string value, string AccountName)
{
foreach(TestClass test in yourListOfTestClass)
{
if (test.GetType().GetProperty(AccountName).GetValue(test, null).Equals(value))
listToReturn.Add(test);
}
return listToReturn
}
Note - Code is not tested. Might have synatx error.
You can send in a method for accessing the property instead of the property name:
public TestClass[] GetTestClass(string value, Func<TestClass, string> getAccountName) {
return accounts.Where(x => getAccountName(x) == value).ToArray();
}
Usage:
TestClass[] johnsAccounts = GetTestClass("John", a => a.Account1);
Or simply use it directly:
TestClass[] johnsAccounts = accounts.Where(a => a.Account1 == "John").ToArray();
Is there a better method of doing this or any thoughts would help.
You can use List of strings instead of multiple string variables as you are returning array from GetTestClass. It will keep it simple as well.
public class TestClass
{
List<string> Accounts = new List<string>();
}
Now you will only pass the value to method. Using the LinQ will filter out the desired string list using Where.
public List<string> GetTestClass(string value)
{
return Accounts.Where(account => account == value).ToList();
}
Edit The OP want two things AccountName and the Name, this would require to have a account class instead of string.
class Account
{
string AccountName { get; set; }
string Name { get; set; }
}
public class TestClass
{
List<Account> Accounts = new List<Account>();
}
public Account GetTestClass(Account account)
{
return Accounts.Where(account => a.AccountName == account.AccountName && a.Name == account.Name).FirstOrDefault();
}
Yes you can do this.
Take a look into Reflection. This should get you started.
Example:
public TestClass[] GetTestClass(string value, string AccountName)
{
var propertyInfo = typeof(TestClass).GetProperty(AccountName);
var list = new List<TestClass>();
foreach(var tc in [YOUR_OBJECTS])
{
if(propertyInfo.GetValue(tc, null) == value)
{
list.add(tc);
}
}
return list.ToArray();
}
Well, you can achieve that using Reflection. Though, I don't think I would do that this way, since there are other ways to implement what you want differently.
A better way in my opinion would be to create a type-safe enum that would do that. In the members of the type-safe enum, you could specify an action that would run against a 'TestClass' object.
You would be able to call 'GetTestClass' in this way:
var accounts1 = GetTestClass(testClassesCollection, "john", TestProperties.Account1);
var accounts2 = GetTestClass(testClassesCollection, "john", TestProperties.Account2);
var accounts3 = GetTestClass(testClassesCollection, "john", TestProperties.Account3);
Where 'testClassesColleciton' is the collection of 'TestClass' that you have. You could remove this argument if the method is an object member.
The type-safe enum is implemented this way:
public sealed class TestProperties
{
public static readonly TestProperties Account1 = new TestProperties((t, name) => t.Account1 == name);
public static readonly TestProperties Account2 = new TestProperties((t, name) => t.Account2 == name);
public static readonly TestProperties Account3 = new TestProperties((t, name) => t.Account3 == name);
private Func<TestClass, string, bool> _checkFunc;
private TestProperties(Func<TestClass, string, bool> func)
{
_checkFunc = func;
}
public bool IsApplicable(TestClass test, string name)
{
return _checkFunc(test, name);
}
}
Then, you can implement the GetTestClass this way:
public TestClass[] GetTestClass(IEnumerable<TestClass> testClasses, string value, TestProperties property)
{
return testClasses.Where( t => property.IsApplicable(t)).ToArray();
}
I wouldn't use reflection because of it's performance overhead and it's maintenance danger. With a plain simple reflection, we will pass the property's name as a string parameter. What would happen if somebody has changed the property's name in the class? Even with Visual Studio refactoring (ctrl + R, R), the string parameter value will not be updated. Since the code will compile normally, the bug will be discovered only at run-time.
I agree with #Rouby that a plain simple reflection will be faster to develop than the type-safe enum way that I have suggested. Though, personally, I don't think that it will be that much cheaper (development-cost wise) and I also think that the potentially dangerous scenario that I talked about earlier (regarding refactoring) would have a bigger development-cost penalty, specially, when it is a legacy/old code.
Maybe this is a trivial problem but I don't really know what is the best way to solve this.
I have a table in my database which columns describe a sensor.
Now there is a column that desribes different types of sensors:
- Heat sensor
- Pressure sensor
and so on...
It's good to use strings here because numbers don't really tell you anything.
Now to retrieve the data from database I use a repository.
public IEnumerable<Sensor> Select(string typeOfSensor)
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session.Query<Sensor>()
.Where(c =>c.TypeOfSensor == typeOfSensor);
}
}
How to make sure that the user will insert the correct name of the sensor ?
I want to avoid using magic strings in my code.
First I thought about using enum but it can't store strings. Than about static classes with static constants but these don't really make the developer to use them since the type will be the same (string) and nothing stops you from not using pre defined types.
How can we do something like this (if enum could store string) ?
enum TypeOfSensor //i know this is not possible but it's for example purposes
{
HeatSensor= "Heat sensor",
PressureSensor = "Pressure sensor"
}
We make sure developer can only insert pre defined strings
var list = _repositorySensors.Select(TypeOfSensor.HeatSensor);
Than in the repository we can get the actual string
public IEnumerable<Sensor> Select(TypeOfSensor typeOfSensor)
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session.Query<Sensor>()
.Where(c =>c.TypeOfSensor == typeOfSensor.Value);
}
}
If it needs to be a string you could use DescriptionAttribute at your enum, to define a custom string per enum Value.
That description value could then be obtained via reflection, for example as an extension method.
enum TypeOfSensor
{
[Description("Heat sensor")]
HeatSensor,
[Description("Pressure sensor")]
PressureSensor
}
private static string ToDescription(this Enum value)
{
var fi = value.GetType().GetField(value.ToString());
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public IEnumerable<Sensor> Select(TypeOfSensor typeOfSensor)
{
using (ISession session = NHibernateHelper.OpenSession())
{
var sensorType = typeOfSensor.ToDescription();
return session.Query<Sensor>()
.Where(c =>c.TypeOfSensor == sensorType );
}
}
If you have a simple case where you'll just be mapping an exact string to your existing enum, you could easily do something like this:
readonly Dictionary<string, TypeOfSensor> SensorTypes =
new Dictionary<string, TypeOfSensor>
{
{"Heat sensor", TypeOfSensor.HeatSensor},
{"Pressure sensor", TypeOfSensor.PressureSensor}
};
Now you can validate your input easily with SensorTypes.ContainsKey("Heat sensor") and you can handle problematic database values appropriately.
You could use something like the below instead of enum:
abstract class TypeOfSensor
{
public static readonly TypeOfSensor HeatSensor =
new HeatTypeOfSensor();
public static readonly TypeOfSensor PressureSensor =
new PressureTypeOfSensor();
private TypeOfSensor() { }
protected abstract string Name { get; }
public static implicit operator string(TypeOfSensor s)
{
return s.Name;
}
private class HeatTypeOfSensor : TypeOfSensor
{
protected override string Name
{
get { return "Heat Sensor"; }
}
}
private class PressureTypeOfSensor : TypeOfSensor
{
protected override string Name
{
get { return "Pressure Sensor"; }
}
}
}
And then:
public IEnumerable<Sensor> Select(TypeOfSensor typeOfSensor)
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session.Query<Sensor>()
.Where(c => c.TypeOfSensor == typeOfSensor);
}
}
some time have passed but this is what I was looking for:
http://blog.falafel.com/introducing-type-safe-enum-pattern/
best answer I found so far. Type-safe Enum pattern. Only I didn't know that it was called like this.
I post this for anyone looking for the answer in the future.
Cheers guys!