Suppose you had the following `enum`

``````public enum Make
{
Toyota,
Subaru
}
``````

And suppose you also had the following `enum`

``````public enum Model
{
Camry,
Forester,
Legacy
}
``````

Finally suppose a `Vehicle` was defined as follows:

``````public class Vehicle
{
public Make Make {get; init;}
public Make Model {get; init;}
}
``````

Looks straightforward enough.

``````var vehicle = new Vehicle
{
Make = Make.Subaru,
Model = Model.Legacy
}
``````

The problem is that you also can do this:

``````var vehicle = new Vehicle
{
Make = Make.Toyota,
Model = Model.Legacy
}
``````

Which is invalid.

If this was a relational database, we would have solved this by storing the `Model` alone, then deriving the make from that from a foreign key relationship.

This is not possible in C#. At least, not directly.

One way to approach this would be to make use of Attributes, with which we can decorate our `enum` values.

We start off by creating an attribute like this:

``````[AttributeUsage(AttributeTargets.Field)]
public class MakeOfAttribute : Attribute
{
public Make Make { get; }
public MakeOfAttribute(Make make)
{
Make = make;
}
}
``````

The line `[AttributeUsage(AttributeTargets.Field)]` indicates that the attribute is meant to be applied to a `Field`, of which an `enum` value is.

We are indicating the attribute takes as a parameter the `Make` of the `Vehicle`.

We can then update our `Model` `enum` as follows:

``````public enum Model
{
[MakeOf(Make.Toyota)]
Camry,
[MakeOf(Make.Toyota)]
[MakeOf(Make.Subaru)]
Forester,
[MakeOf(Make.Subaru)]
Legacy
}
``````

Thus you can tell by looking what `Model` applies to which `Make`. We can further make use of this to enforce the connection.

We need to write some code that, given the `Model`, will get for us the `Make` specified as an attribute.

We can make us of .NET reflection for this purpose.

We can remove `Make` from the `Vehicle` class directly and retrieve it as follows:

``````public class Vehicle
{
public Make Make
{
get
{
return _model.GetType() // Retrieve the type
.GetMember(_model.ToString()) //Get the member info for the passed field (Camry)
.First() // Retrieve the first item
.GetCustomAttribute<MakeOfAttribute>()! // Get the attribute specified
.Make; // Get the make and return it
}
}
public Model Model => _model;

public Vehicle(Model model)
{
_model = model;
}
}
``````

Of particular emphasis here is that the `Make` property is completely derived from the `Model`, and therefore it is not at the discretion of the developer to set it.

Our final program will look like this:

``````var vehicle = new Vehicle(Model.Camry);
Console.WriteLine(\$"Model: {vehicle.Model}");
Console.WriteLine(\$"Make: {vehicle.Make}");
``````

This should print the following to your console:

``````Model: Camry
Make: Toyota
``````

The code is in my Github.

Happy hacking!
{"ft_lang_label":"__label__en","ft_lang_prob":0.7962843,"math_prob":0.78727156,"size":2763,"snap":"2023-40-2023-50","text_gpt3_token_len":661,"char_repetition_ratio":0.14280537,"word_repetition_ratio":0.040632054,"special_character_ratio":0.2334419,"punctuation_ratio":0.15503876,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.97303367,"pos_list":[0,1,2],"im_url_duplicate_count":[null,1,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-09-25T10:33:21Z\",\"WARC-Record-ID\":\"<urn:uuid:acdb6b05-f331-4fce-8623-47adb2b06784>\",\"Content-Length\":\"17988\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:1081468d-4740-4d6c-9d76-03a3e79df65c>\",\"WARC-Concurrent-To\":\"<urn:uuid:cfc28967-47f4-4a45-8228-ad2e51b19d49>\",\"WARC-IP-Address\":\"69.163.186.112\",\"WARC-Target-URI\":\"http://www.conradakunga.com/blog/enum-attributes-for-enum-values-in-c/\",\"WARC-Payload-Digest\":\"sha1:ZBPZ34Y7M3SU2UYIN2YKTHMDSWQBOW2Z\",\"WARC-Block-Digest\":\"sha1:CKC6QJZXAP5VWKACLQV2E23X7GMGOSKG\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-40/CC-MAIN-2023-40_segments_1695233508959.20_warc_CC-MAIN-20230925083430-20230925113430-00470.warc.gz\"}"}