C# : Enum and overriding ToString on it

來源:互聯網
上載者:User

本文轉自:http://blogs.msdn.com/abhinaba/archive/2005/10/20/483000.aspx

 

I saw two posts on Enums today on Eric Lipperts and Chris Rathjen's blog. Enums are significantly different from the other types and people run into unusal problems while working with them.

C++

The CLI enum is considerably different from the native C++ enum and therefore you need to be careful how you define and use them in Managed C++. In new syntax (C++/CLI whidbey) the following code compiles even though both the enums define the same name Cool.

enum

class Coolness // class indicates this is a C++/CLI enum

{

NotSoCool,

Cool,

SuperCool

};

enum

class TempRange

{

Cool,

Hot,

VeryHot,

};

In old syntax (pre whidbey) you need to define the enum as __value enum Coolness. In case you drop the class then you are using the native C++ enum and according to C++ specification the enumerator declarations are promoted to the same scope as the enumerated type declaration and the code will fail to compile pointing out a redefinition of Cool.

C#

In C# we do need not care about these as there is only one definition of enum which is that of the CLI enum.

Common things like the first enum member get the value 0, the value of a subsequent member is calculated by adding 1 to the member textually preceeding it, you can assign values explicitely to a enum member are well-known. However there are some not so well known usages as well.

enum Coolness : byte

{

NotSoCool = 5,

Cool,

VeryCool = NotSoCool + 7,

SuperCool

}

Coolness

coolType = Coolness.VeryCool;

Console

.WriteLine("Underlying type: {0}", Enum.GetUnderlyingType(coolType.GetType()));

Console.WriteLine("Type Code : {0}", coolType.GetTypeCode());

Console.WriteLine("Value : {0}", (byte)coolType);

By default the compiler uses Int32 to store the enum members. Here we are asking it to use byte. VeryCool uses a reference to the NotSoCool and will get the value 12. So the out put of the code above will be

Underlying type: System.Byte
Type Code      : Byte
Value          : 12

Since all enums have System.Enum as the abstract base type, a lot of funcionality becomes available to get details about the enum type.

If you want to print the value of the enum then it can be done in the following ways

Console

.WriteLine(coolType.ToString("G")); // name of the constant

Console.WriteLine(coolType.ToString("F")); // name of the constant

Console.WriteLine(coolType.ToString("X")); // value is hex

Console.WriteLine(coolType.ToString("D")); // value in decimalOutput:
VeryCoolVeryCool0C12

F and G gives the same value in this case. They differ based on whether FlagsAttribute is applied to it.

You can also get a array filled with either the value (GetValues) or names (GetNames) of all the constants in the enum.

string

[] names = Enum.GetNames(typeof(Coolness));

int index = 0;

foreach (Coolness coolVal in Enum.GetValues(typeof(Coolness)))

{

Console.WriteLine("{0,-10} => {1}", names[index++],

coolVal.ToString(

"D"));

}

This prints

NotSoCool  => 5
Cool       => 6
VeryCool   => 12
SuperCool  => 13

You can also query the name of the constant in the enum that has the specified value or whether a value is defined in the enum or not. The following will print cool and 5 is not defined.

Console

.WriteLine(Enum.GetName(typeof(Coolness), 6));

if(!Enum.IsDefined(typeof(Coolness), (byte)7))

Console.WriteLine("5 is Not Defined");

Overriding ToString()

You cannot override the ToString of the enum type. So in case you wanted to display "Not so cool" instead of NotSoCool when someone called ToString on your enum type then you cannot do that simply by overriding the ToString.

This is a common issue that comes up frequently when you want to show values in reports, web pages, XML where you want to put in human readable text for enum values. Commonly people use non-generic solution of maintaining arrays of these descriptions and get text out of them by indexing using the enum value or some other things like storing it in a hashtable and using the ToString value as the key to get the desciption out.

A generic solution would be to apply custom attributes on the enum constants and write static methods to get the desciption. See the modified code below

using

System;

using

System.Reflection;

namespace

FunWithEnum

{

enum Coolness : byte

{

[

Description("Not so cool")]

NotSoCool = 5,

Cool,

// since description same as ToString no attr are used

[

Description("Very cool")]

VeryCool = NotSoCool + 7,

[

Description("Super cool")]

SuperCool

}

class Description : Attribute

{

public string Text;

public Description(string text)

{

Text = text;

}

}

class Program

{

static string GetDescription(Enum en)

{

Type type = en.GetType();

MemberInfo[] memInfo = type.GetMember(en.ToString());

if (memInfo != null && memInfo.Length > 0)

{

object[] attrs = memInfo[0].GetCustomAttributes(typeof(Description),
false
);

if (attrs != null && attrs.Length > 0)

return ((Description)attrs[0]).Text;

}

return en.ToString();

}

static void Main(string[] args)

{

Coolness coolType1 = Coolness.Cool;

Coolness coolType2 = Coolness.NotSoCool;

Console.WriteLine(GetDescription(coolType1));

Console.WriteLine(GetDescription(coolType2));

}

}

}

Using this approach is pretty generic because for all enum constants that have this attribute applied to it, the desciption will be picked up from it and for those that do not have the attribute the common ToString() method will be called to get the description. However, the GetDescription uses reflection and can be slow.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.