简体   繁体   中英

Representing “comboboxes” in C#

I have to do a form in which has several comboboxes. Comboboxes have values represented as Key-Description pairs.

Each Combobox has its values in a separate table Key<string> - Value<string>

How to represent it in a class?
Suppose we have Project ( Type and Technology ) as "enums", each of them in Type and Technology tables in Database (so its number depends on how many rows in the DB)

class Project {
    public int Id {get; set;}
    public KeyValuePair<string, string> Type {get; set;}
    public KeyValuePair<string, string> Technology {get; set;}
}

or better

class ProjectType { public string Key; public string Value; }
class ProjectTechnology { public string Key; public string Value; }

class Project {
    public int Id {get; set;}
    public ProjectType Type {get; set;}
    public ProjectTechnolgy Technology {get; set;}
}

From the point of view of the separation of concerns probably we should use the second variant, but why to complicate if we could do simple like in the first ?

Suppose we have Project (Type and Technology) as "enums", each of them in Type and Technology tables in Database

Then why not to use enums?

public enum ProjectType
    {
        [Description("Friendly name for type 1")]
        Type1,
        [Description("Friendly name for type 2")]
        Type2,
        [Description("Friendly name for type 3")]
        Type3
    }

And with an extension method like the following you can get the description of a given enum value:

public static string GetEnumDescription<TEnum>(this TEnum item)
        => item.GetType()
               .GetField(item.ToString())
               .GetCustomAttributes(typeof(DescriptionAttribute), false)
               .Cast<DescriptionAttribute>()
               .FirstOrDefault()?.Description ?? string.Empty;

(I got this code frome here , where also is shown how to map enums to tables in the case your are using EF as ORM)

The Description attribute can be used as the display string inside your combobox. This way works if, as you say, the values are fixed, if they are not or they may grow or change then I would say the second approach (creating separate classes) is better following SOLID best practices, in this case I would say that the second approach violates the O and the S in solid, the Open-closed Principle and the Single Responsibility Principle (more on SOLID ).

Let's say Types and Technologies may grow or change, and you follow the first approach. Then you violate the S since now your Project class may change if the definition of Type or Technology changes. Supouse that in the future you realize that you must support mutiple languages (eng, esp, ita, etc), then you violate the O since the definition of Type and Technology can not be anymore represented by a KeyValuePair and you will have to figure out how to achieve this and, worst, you will have to modify Project class which should take no care about this.

But if they are fixed values then the enum approach is better since it enforces to use always known values, there is no chance that you can assign to a Project a Type or a Technology that does not exist.

This is a matter of opinion and coding style, but here's my take:

The first option (simple KeyValuePair) is less code, but that doesn't neccesarily make it simpler. The second option (creating classes to represent ProjectType and ProjectTechnology) is better, because it is much easier to read.

A further improvement (my opinion again) would be not to name the properties of these two classes "Key" and "Value". Surely these properties represent something more specific than a key and a value? Name it accordingly, making it easier for others to understand what they represent.

Hope that's the kind of answer you needed.

PS it's fairly clear what you meant to write, but you forgot to remove the 'int' in

public int KeyValuePair<string, string> Type {get; set;}
public int KeyValuePair<string, string> Technology {get; set;}

and

 public int ProjectType Type { get; set;}
 public int ProjectTechnolgy Technology { get; set;}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM