එනූම් වල නූල් නිරූපණය


918

මට පහත ගණනය කිරීම් ඇත:

public enum AuthenticationMethod
{
    FORMS = 1,
    WINDOWSAUTHENTICATION = 2,
    SINGLESIGNON = 3
}

කෙසේ වෙතත් ගැටළුව වන්නේ මට AuthenticationMethod.FORMS ඉල්ලන විට "FORMS" යන වචනය අවශ්‍ය වන අතර එය id 1 නොවේ.

මෙම ගැටළුව සඳහා මම පහත විසඳුම සොයාගෙන ඇත ( සබැඳිය ):

පළමුව මට "StringValue" නමින් අභිරුචි ගුණාංගයක් නිර්මාණය කළ යුතුය:

public class StringValue : System.Attribute
{
    private readonly string _value;

    public StringValue(string value)
    {
        _value = value;
    }

    public string Value
    {
        get { return _value; }
    }

}

එවිට මට මෙම ගුණාංගය මගේ ගණන්කරුට එකතු කළ හැකිය:

public enum AuthenticationMethod
{
    [StringValue("FORMS")]
    FORMS = 1,
    [StringValue("WINDOWS")]
    WINDOWSAUTHENTICATION = 2,
    [StringValue("SSO")]
    SINGLESIGNON = 3
}

ඇත්ත වශයෙන්ම මට එම StringValue ලබා ගැනීමට යමක් අවශ්‍යයි:

public static class StringEnum
{
    public static string GetStringValue(Enum value)
    {
        string output = null;
        Type type = value.GetType();

        //Check first in our cached results...

        //Look for our 'StringValueAttribute' 

        //in the field's custom attributes

        FieldInfo fi = type.GetField(value.ToString());
        StringValue[] attrs =
           fi.GetCustomAttributes(typeof(StringValue),
                                   false) as StringValue[];
        if (attrs.Length > 0)
        {
            output = attrs[0].Value;
        }

        return output;
    }
}

හොඳයි දැන් මට ගණන් ගැනීමේ යන්ත්‍රයක් සඳහා නූල් අගයක් ලබා ගැනීමට මෙවලම් තිබේ. මට එය මේ ආකාරයෙන් භාවිතා කළ හැකිය:

string valueOfAuthenticationMethod = StringEnum.GetStringValue(AuthenticationMethod.FORMS);

හරි, දැන් මේ සියල්ලම චාම් එකක් වගේ නමුත් මට එය සම්පූර්ණ වැඩක්. මේ සඳහා වඩා හොඳ විසඳුමක් තිබේදැයි මම කල්පනා කළෙමි.

මම ශබ්ද කෝෂයක් සහ ස්ථිතික ගුණාංග ඇති යමක් උත්සාහ කළ නමුත් එයද හොඳ නැත.


8
හොඳයි! දේශීයකරණය කරන ලද නූල් වලට enum අගයන් පරිවර්තනය කිරීමට මට මෙය භාවිතා කළ හැකිය.
අයිවින්ඩ් ස්කාර්

5
ඔබට මෙම දිගු සුළං ඇති බව පෙනෙන්නට තිබුණද, ඇත්ත වශයෙන්ම එය වෙනත් දේ සඳහා යාමට නම්යශීලී ක්‍රමයකි. මගේ සගයකු පෙන්වා දුන් පරිදි, මෙය බොහෝ අවස්ථාවලදී දත්ත සමුදා කේත
සංඛ්‍යාත්මක

27
MSDN ප්‍රතිග්‍රාහක උපසර්ගය "ගුණාංග" උපසර්ගය සහිත උපලක්ෂණ පංති. එබැවින් "class StringValueAttribute";)
serhio

14
En බෙන් ඇලබාස්ටර් සමඟ මම එකඟ වෙමි මෙය සැබවින්ම නම්‍යශීලී වේ. ඔබේ ස්ථිතික ක්‍රමයට thisඉදිරියෙන් එකතු කිරීමෙන් ඔබට මෙය දිගු කිරීමේ ක්‍රමයක් බවට පත් කළ හැකිය Enum. එවිට ඔබට කළ හැකිය AuthenticationMethod.Forms.GetStringValue();
ජස්ටින් පිහෝනි

5
මෙම ප්‍රවේශය මඟින් ගුණාංග අගයන් කියවීමට පරාවර්තනය භාවිතා කරන අතර මගේ අත්දැකීම් වලදී ඔබට GetStringValue () ඇමතීමට සිදුවුවහොත් එය ඉතා මන්දගාමී වේ. ටයිප්-සේෆ්-එනුම් රටාව වේගවත් ය.
Rn222

Answers:


869

Type-safe-enum රටාව උත්සාහ කරන්න .

public sealed class AuthenticationMethod {

    private readonly String name;
    private readonly int value;

    public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (1, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (2, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (3, "SSN");        

    private AuthenticationMethod(int value, String name){
        this.name = name;
        this.value = value;
    }

    public override String ToString(){
        return name;
    }

}

යාවත්කාලීන කරන්න පැහැදිලි (හෝ ව්‍යංග) ආකාරයේ පරිවර්තනයක් කළ හැකිය

  • සිතියම්ගත කිරීම සමඟ ස්ථිතික ක්ෂේත්‍රය එකතු කිරීම

    private static readonly Dictionary<string, AuthenticationMethod> instance = new Dictionary<string,AuthenticationMethod>();
    • නිදර්ශන සාදන්නා අමතන විට “එනුම් සාමාජික” ක්ෂේත්‍ර ආරම්භ කිරීම ශුන්‍ය යොමු විමසුමක් නොදක්වන පිණිස, ශබ්දකෝෂ ක්ෂේත්‍රය ඔබේ පන්තියේ “එනුම් සාමාජික” ක්ෂේත්‍රයට පෙර තැබීමට වග බලා ගන්න. මෙයට හේතුව, ස්ථිතික ක්ෂේත්‍ර ආරම්භකයින් ප්‍රකාශන අනුපිළිවෙලට කැඳවීම සහ ස්ථිතික ඉදිකිරීම්කරුට පෙර, සියලු ස්ථිතික ක්ෂේත්‍ර ආරම්භ කිරීමට පෙර සහ ස්ථිතික ඉදිකිරීම්කරු කැඳවීමට පෙර නිදර්ශන ඉදිකිරීම්කරු කැඳවිය හැකි අමුතු හා අවශ්‍ය නමුත් ව්‍යාකූල තත්වයක් නිර්මාණය කිරීමයි.
  • නිදර්ශන සාදන්නා තුළ මෙම සිතියම්ගත කිරීම

    instance[name] = this;
  • සහ පරිශීලක අර්ථ දක්වන ආකාරයේ පරිවර්තන ක්‍රියාකරු එක් කිරීම

    public static explicit operator AuthenticationMethod(string str)
    {
        AuthenticationMethod result;
        if (instance.TryGetValue(str, out result))
            return result;
        else
            throw new InvalidCastException();
    }

19
එය එනුම් එකක් මෙන් පෙනුනද එය එනුම් නොවේ. AuthenticationMethods සංසන්දනය කිරීමට මිනිසුන් උත්සාහ කළහොත් සිත්ගන්නා සුළු ගැටලු ඇති වේ යැයි මට සිතාගත හැකිය. ඔබට විවිධ සමානාත්මතා ක්‍රියාකරුවන් ද අධික ලෙස පැටවීමට අවශ්‍ය වනු ඇත.
කුහුඹුවා

36
Nt: මට අවශ්‍ය නැහැ. එක් එක් සත්‍යාපන ක්‍රමයේ එක් අවස්ථාවක් පමණක් අප සතුව ඇති හෙයින්, වස්තුවෙන් උරුම වූ යොමු සමානාත්මතාවය හොඳින් ක්‍රියාත්මක වේ.
Jakub Šturc

10
rytyriker: සම්පාදකයා කරයි. ඉදිකිරීම්කරු පුද්ගලික බැවින් ඔබට නව අවස්ථාවක් නිර්මාණය කළ නොහැක. ස්ථිතික සාමාජිකයින්ට උදාහරණ හරහා ප්‍රවේශ විය නොහැක.
Jakub Šturc

21
Ak ජාකුබ් ඉතා රසවත්. එය භාවිතා කරන්නේ කෙසේදැයි සොයා ගැනීමට සහ එහි ප්‍රතිලාභ අවබෝධ කර ගැනීමට මට එය සමඟ සෙල්ලම් කිරීමට සිදු විය. එය පොදු, ස්ථිතික නොවන පන්තියකි, නමුත් එය ක්ෂණිකව කළ නොහැකි අතර ඔබට එහි ස්ථිතික සාමාජිකයින්ට පමණක් ප්‍රවේශ විය හැකිය. මූලික වශයෙන්, එය එනුම් ලෙස හැසිරේ. නමුත් හොඳම කොටස ... ස්ථිතික සාමාජිකයන් පන්තියේ යතුරු ලියනය කර ඇති අතර සාමාන්‍ය නූල් හෝ int නොවේ. එය ... [ඒ සඳහා රැඳී සිටින්න] ... ආරක්ෂිත එනුම් ටයිප් කරන්න! මට තේරුම් ගැනීමට උදව් කිරීම ගැන ස්තූතියි.
tyriker

6
@kiran මම ස්විච්-කේස් ප්‍රකාශ සමඟ භාවිතා කිරීමට ඉඩ සලසන ජකුබ් ur ටර්ක්ගේ පිළිතුරෙහි තරමක් වෙනස් කළ අනුවාදයක් පහත පළ කර ඇත්තෙමි, එබැවින් දැන් මෙම ප්‍රවේශයට කිසිදු අවාසියක් නොමැත :)
මාරාන්තික

229

ක්රමය භාවිතා කරන්න

Enum.GetName(Type MyEnumType,  object enumvariable)  

මෙන් (උපකල්පනය Shipperයනු අර්ථ දක්වා ඇති එනුම්)

Shipper x = Shipper.FederalExpress;
string s = Enum.GetName(typeof(Shipper), x);

එනුම් පන්තියේ වෙනත් ස්ථිතික ක්‍රම රාශියක් ද විමර්ශනය කිරීම වටී ...


5
හරියටම. මම සංගීත විස්තරයක් සඳහා අභිරුචි ගුණාංගයක් සාදන ලදී, නමුත් එයට හේතුව මට පරිශීලක-හිතකාමී අනුවාදයක් (අවකාශයන් සහ වෙනත් විශේෂ අක්ෂර සහිත) අවශ්‍ය වන අතර එය පහසුවෙන් කොම්බොබොක්ස් හෝ ඊට සම්බන්ධ කළ හැකිය.
එල්සී.

5
Enum.GetName මගින් enum හි ක්ෂේත්‍ර නාම පිළිබිඹු වේ - .ToString (). කාර්ය සාධනය ගැටලුවක් නම් එය ගැටළුවක් විය හැකිය. ඔබ එනමුත් විශාල ප්‍රමාණයක් පරිවර්තනය කළොත් මිස මම ඒ ගැන කරදර නොවෙමි.
කීත්

8
සලකා බැලිය යුතු තවත් විකල්පයක් නම්, ඔබට වැඩිපුර විනෝදකාමී බවක් අවශ්‍ය නම්, ව්‍යුහයක් භාවිතා කර “ඔබේම රෝල් කිරීම” ... ව්‍යුහයේ තනි අවස්ථා උත්පාදනය කරන ඉදිකිරීම්කරුවන්ට ආරම්භ කර ඇති එනුම් අගයන් නිරූපණය කිරීම සඳහා ඔබ ස්ථිතික කියවීමට පමණක් නම් කළ ගුණාංග එකතු කරයි. ...
චාල්ස් බ්‍රෙටනා

1
එවිට ඔබට අවශ්‍ය ඕනෑම ව්‍යුහාත්මක සාමාජිකයන් එකතු කර ගත හැකි අතර, මෙම “එනුම්” ලබා ගැනීමට අවශ්‍ය ඕනෑම ක්‍රියාකාරකමක් ක්‍රියාත්මක කිරීමට ...
චාල්ස් බ්‍රෙටනා

2
මෙහි ඇති ගැටළුව නම් GetName දේශීයකරණය කළ නොහැකි වීමයි. එය සැමවිටම සැලකිලිමත් නොවන නමුත් එය දැනුවත් විය යුතු දෙයකි.
ජොයෙල් කොහූර්

79

ToString () භාවිතා කිරීමෙන් ඔබට වටිනාකමට වඩා නම සඳහන් කළ හැකිය

Console.WriteLine("Auth method: {0}", AuthenticationMethod.Forms.ToString());

ප්‍රලේඛනය මෙහි ඇත:

http://msdn.microsoft.com/en-us/library/16c1xs4z.aspx

... සහ ඔබ පැස්කල් නඩුවේදී ඔබේ එනූම්ස් නම් කළහොත් (මා කරන පරිදි - මෙයIISMyEnumValue = 1 යනාදිය) එවිට ඔබට සුහද ස්වරූපය මුද්‍රණය කිරීම සඳහා ඉතා සරල රීජෙක්ස් භාවිතා කළ හැකිය:

static string ToFriendlyCase(this string EnumString)
{
    return Regex.Replace(EnumString, "(?!^)([A-Z])", " $1");
}

ඕනෑම නූලකින් පහසුවෙන් කැඳවිය හැකි:

Console.WriteLine("ConvertMyCrazyPascalCaseSentenceToFriendlyCase".ToFriendlyCase());

නිමැවුම්:

මගේ පිස්සු පැස්කල් නඩු වාක්‍යය මිත්‍රශීලී නඩුවක් බවට පරිවර්තනය කරන්න

එමඟින් නිවෙස් පුරා ධාවනය වන පරිදි අභිරුචි ගුණාංග නිර්මාණය කර ඒවා ඔබේ එනූම් වලට අනුයුක්ත කිරීම හෝ සුහද නූලක් සහිත එනුම් වටිනාකමක් විවාහ කර ගැනීම සඳහා විමසුම් වගු භාවිතා කිරීම සහ සියල්ලටම වඩා එය ස්වයං කළමනාකරණය වන අතර අනන්තවත් ඕනෑම පැස්කල් කේස් නූලක භාවිතා කළ හැකිය. වඩාත් නැවත භාවිතා කළ හැකිය. ඇත්ත වශයෙන්ම, ඔබේ විසඳුම සපයන ඔබේ එනුම් වලට වඩා වෙනස් මිත්‍රශීලී නමක් ලබා ගැනීමට එය ඉඩ නොදේ .

වඩාත් සංකීර්ණ අවස්ථාවන්හිදී වුවද මම ඔබේ මුල් විසඳුමට කැමතියි. ඔබට ඔබේ විසඳුම තවත් එක් පියවරක් ඉදිරියට ගෙන ගොස් ඔබේ GetStringValue ඔබේ enum හි ව්‍යාප්ති ක්‍රමයක් බවට පත් කළ හැකි අතර පසුව ඔබට එය StringEnum.GetStringValue ලෙස සඳහන් කිරීමට අවශ්‍ය නොවේ.

public static string GetStringValue(this AuthenticationMethod value)
{
  string output = null;
  Type type = value.GetType();
  FieldInfo fi = type.GetField(value.ToString());
  StringValue[] attrs = fi.GetCustomAttributes(typeof(StringValue), false) as StringValue[];
  if (attrs.Length > 0)
    output = attrs[0].Value;
  return output;
}

එවිට ඔබට ඔබේ enum නිදසුනෙන් පහසුවෙන් එය වෙත පිවිසිය හැකිය:

Console.WriteLine(AuthenticationMethod.SSO.GetStringValue());

2
"මිත්‍රශීලී නමට" ඉඩක් අවශ්‍ය නම් මෙය උදව් නොකරයි. "පෝරම සත්‍යාපනය" වැනි
රේ බූයිසන්

4
එබැවින් එනුම් නම් කර ඇත්තේ FormsAuthentication වැනි තොප්පි වලින් බව සහතික කර ආරම්භයේ නොමැති ඕනෑම තොප්පියකට පෙර ඉඩක් ඇතුල් කරන්න.
නූලක

4
පැස්කල් කේස් නම් වල ස්වයංක්‍රීය පරතරය ප්‍රාග්ධනීකරණය කළ යුතු කෙටි යෙදුම් අඩංගු නම් ගැටළු සහගත වේ, උදාහරණයක් ලෙස එක්ස්එම්එල් හෝ ජීපීඑස්.
රිචඩ් එව්

2
Ic රිචාර්ඩ් ඊව්, මේ සඳහා පරිපූර්ණ රීජෙක්ස් එකක් නැත, නමුත් මෙහි කෙටි යෙදුම් සමඟ මඳක් හොඳින් ක්‍රියා කළ යුතු එකකි. "(?!^)([^A-Z])([A-Z])", "$1 $2". එසේ HereIsATESTබවට පත්වේ Here Is ATEST.
අමතර කොටස්

මෙම කුඩා "හක්ක" කිරීම එතරම් වැදගත් නොවේ. OP පවසන දේ මට ලැබෙන අතර ඒ හා සමාන විසඳුමක් සොයා ගැනීමට මම උත්සාහ කරමි, එනම් එනූම්ස්හි අලංකාරය භාවිතා කරමින් නමුත් සම්බන්ධිත පණිවිඩයට පහසුවෙන් ප්‍රවේශ විය හැකිය. මට සිතිය හැකි එකම විසඳුම වන්නේ එනුම් නාමය සහ නූල් අගය අතර යම් ආකාරයක සිතියම් ගත කිරීමකි, නමුත් එය නූල් දත්ත නඩත්තු කිරීමේ ගැටලුව විසඳන්නේ නැත (කෙසේ වෙතත් ඔබට බහු කලාප තිබිය යුතු අවස්ථා සඳහා එය ප්‍රායෝගික කරයි. )
තාහීර් කාලිඩ්

73

අවාසනාවට, එනූම්ස් මත ගුණාංග ලබා ගැනීම පරාවර්තනය තරමක් මන්දගාමී ය:

මෙම ප්‍රශ්නය බලන්න: එනුම් වටිනාකමක් මත අභිරුචි ගුණාංග ලබා ගැනීමට ඉක්මන් ක්‍රමයක් ඕනෑම අයෙක් දන්නවාද?

මෙම .ToString()ඉතා enums මත ඉතා මන්දගාමී වේ.

එනමුත් සඳහා ඔබට දිගු කිරීමේ ක්‍රම ලිවිය හැකිය:

public static string GetName( this MyEnum input ) {
    switch ( input ) {
        case MyEnum.WINDOWSAUTHENTICATION:
            return "Windows";
        //and so on
    }
}

මෙය විශිෂ්ට නොවේ, නමුත් ඉක්මන් වනු ඇති අතර ගුණාංග හෝ ක්ෂේත්‍ර නාම සඳහා පරාවර්තනය අවශ්‍ය නොවේ.


සී # 6 යාවත්කාලීන කිරීම

ඔබ C, # 6 භාවිතා කළ හැකි නම්, එවිට එම නව nameofක්රියාකරු enums සඳහා ක්රියා නිසා nameof(MyEnum.WINDOWSAUTHENTICATION)බවට පරිවර්තනය වනු ඇත "WINDOWSAUTHENTICATION"දී ඇති බැදීමකට එය ලබා නිඛිල නම් කිරීමට ඉක්මන්ම මාර්ගය කරමින්,.

මෙය පැහැදිලි එනූමය ආනත නියතයක් බවට පරිවර්තනය කරන බව සලකන්න, එබැවින් ඔබට විචල්‍යයක ඇති එනූම් සඳහා එය ක්‍රියා නොකරයි. නිසා:

nameof(AuthenticationMethod.FORMS) == "FORMS"

ඒත්...

var myMethod = AuthenticationMethod.FORMS;
nameof(myMethod) == "myMethod"

24
ඔබට එක් වරක් ආරෝපණ අගයන් ලබා ගත හැකි අතර ප්‍රකාශන අංගය තබා ගැනීම සඳහා ඒවා <MyEnum, string> ශබ්ද කෝෂයකට දැමිය හැකිය.
ජෝන් ස්කීට්

1
ඔව්, අපි පරාවර්තනය බෝතල්-බෙල්ල බව දැනගත් විට, අපි බොහෝ එන්මූම් සහිත යෙදුමක එය කළෙමු.
කීත්

ස්තූතියි ජෝන් සහ කීත්, මම ඔබේ ශබ්ද කෝෂ යෝජනාව භාවිතා කළා. විශිෂ්ටයි (හා වේගවත්!).
හෙල්ජ් ක්ලයින්

On ජෝන්ස්කීට් මම දන්නවා මේක පරණයි කියලා. නමුත් යමෙක් මෙය සාක්ෂාත් කරගන්නේ කෙසේද?
user919426

2
@ user919426: අවශ්‍යද? ඒවා ශබ්ද කෝෂයකට දමන්නේද? එකතු කිරීමේ ආරම්භකය සමඟ ඉතා හොඳින් ශබ්ද කෝෂයක් සාදන්න ... ඔබ ඉල්ලන්නේ කුමක්ද යන්න පැහැදිලි නැත.
ජෝන් ස්කීට්

59

මම දිගු කිරීමේ ක්‍රමයක් භාවිතා කරමි:

public static class AttributesHelperExtension
    {
        public static string ToDescription(this Enum value)
        {
            var da = (DescriptionAttribute[])(value.GetType().GetField(value.ToString())).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return da.Length > 0 ? da[0].Description : value.ToString();
        }
}

දැන් පහත පරිදි සැරසීම enum:

public enum AuthenticationMethod
{
    [Description("FORMS")]
    FORMS = 1,
    [Description("WINDOWSAUTHENTICATION")]
    WINDOWSAUTHENTICATION = 2,
    [Description("SINGLESIGNON ")]
    SINGLESIGNON = 3
}

ඔබ අමතන විට

AuthenticationMethod.FORMS.ToDescription()ඔබට ලැබෙනු ඇත "FORMS".


1
මට එකතු කිරීමට සිදු විය, using System.ComponentModel;තවද, මෙම ක්‍රමය ක්‍රියාත්මක වන්නේ ඔබට නූල් අගය එනුම්ගේ නමට සමාන වීමට අවශ්‍ය නම් පමණි. OP ට වෙනස් වටිනාකමක් අවශ්‍ය විය.
elcool

2
ඔබ අමතන විට අදහස් කරන්නේ AuthenticationMethod.FORMS.ToDescription()නැද්ද?
nicodemus13

41

ToString()ක්රමය භාවිතා කරන්න

public enum any{Tomato=0,Melon,Watermelon}

නූල යොමු කිරීමට Tomato, භාවිතා කරන්න

any.Tomato.ToString();

වොව්. එය පහසු විය. අභිරුචි නූල් විස්තර එකතු කිරීමට OP ට අවශ්‍ය බව මම දනිමි, නමුත් මට අවශ්‍ය වූයේ මෙයයි. නැවත සලකා බැලීමේදී මෙය අත්හදා බැලීමට මා දැන සිටිය යුතුව තිබුනි, නමුත් මම Enum.GetName මාර්ගයෙන් බැස ගියෙමි.
Rafe

7
අනෙක් සියල්ලන්ම මෙය ඕනෑවට වඩා සංකීර්ණ කරන්නේ ඇයි?
බ්‍රෙන්ට්

18
-බ්‍රෙන්ට් නිසා බොහෝ විට ඔබට අවශ්‍ය .ToString()පරිශීලක-හිතකාමී වටිනාකමට වඩා වෙනස් අගයක් ඇත.
නොවිචි එස්

2
@ බ්‍රෙන්ට් - මෙය අසන ප්‍රශ්නයට වඩා වෙනස් නිසා. අසනු ලබන ප්‍රශ්නය නම් ගණනය කළ අගයක් ලබා දී ඇති විචල්‍යයකින් ඔබ මෙම නූල ලබා ගන්නේ කෙසේද යන්නයි. ධාවන වේලාවේදී එය ගතිකය. මෙය වර්ගයෙහි අර්ථ දැක්වීම පරීක්ෂා කර ධාවන වේලාවට සකසා ඇත.
හොගන්

1
Og හොගන් - ටොස්ට්‍රිං () විචල්‍යයන් මත ද ක්‍රියා කරයි: any fruit = any.Tomato; string tomato = fruit.ToString();
ලිබෝර්වී

29

.Net 4.0 සහ ඊට ඉහළින් ඉතා සරල විසඳුමක්. වෙනත් කේතයක් අවශ්‍ය නොවේ.

public enum MyStatus
{
    Active = 1,
    Archived = 2
}

හුදෙක් භාවිතා කිරීම පිළිබඳ නූල ලබා ගැනීමට:

MyStatus.Active.ToString("f");

හෝ

MyStatus.Archived.ToString("f");`

වටිනාකම "සක්‍රීය" හෝ "සංරක්ෂිත" වනු ඇත.

අමතන විට විවිධ නූල් ආකෘති (ඉහළින් "f") Enum.ToStringබැලීමට මෙම ගණන් ගැනීමේ ආකෘති නූල් පිටුව බලන්න


28

මම System.ComponentModel නාම අවකාශයෙන් විස්තර ගුණාංගය භාවිතා කරමි. සරලවම enum අලංකාර කර එය ලබා ගැනීමට මෙම කේතය භාවිතා කරන්න:

public static string GetDescription<T>(this object enumerationValue)
            where T : struct
        {
            Type type = enumerationValue.GetType();
            if (!type.IsEnum)
            {
                throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
            }

            //Tries to find a DescriptionAttribute for a potential friendly name
            //for the enum
            MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
            if (memberInfo != null && memberInfo.Length > 0)
            {
                object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0)
                {
                    //Pull out the description value
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            //If we have no description attribute, just return the ToString of the enum
            return enumerationValue.ToString();

        }

උදාහරණයක් ලෙස:

public enum Cycle : int
{        
   [Description("Daily Cycle")]
   Daily = 1,
   Weekly,
   Monthly
}

මෙම කේතය ඔබට "මිත්‍රශීලී නමක්" අවශ්‍ය නොවන එනූම් සඳහා මනාව සපුරාලයි.


27

මම ඇත්තටම ජකුබ් එටුර්ක්ගේ පිළිතුරට කැමතියි, නමුත් එහි අඩුපාඩුව නම් ඔබට එය ස්විච්-කේස් ප්‍රකාශයක් සමඟ භාවිතා කළ නොහැකි වීමයි. ස්විච් ප්‍රකාශයක් සමඟ භාවිතා කළ හැකි ඔහුගේ පිළිතුරේ තරමක් වෙනස් කළ අනුවාදය මෙන්න:

public sealed class AuthenticationMethod
{
    #region This code never needs to change.
    private readonly string _name;
    public readonly Values Value;

    private AuthenticationMethod(Values value, String name){
        this._name = name;
        this.Value = value;
    }

    public override String ToString(){
        return _name;
    }
    #endregion

    public enum Values
    {
        Forms = 1,
        Windows = 2,
        SSN = 3
    }

    public static readonly AuthenticationMethod FORMS = new AuthenticationMethod (Values.Forms, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION = new AuthenticationMethod (Values.Windows, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON = new AuthenticationMethod (Values.SSN, "SSN");
}

එබැවින් ඔබට ජකූබ් එටුර්ක්ගේ පිළිතුරේ සියලු ප්‍රතිලාභ ලැබෙනු ඇත, තවද අපට එය ස්විච් ප්‍රකාශයක් සමඟ භාවිතා කළ හැකිය:

var authenticationMethodVariable = AuthenticationMethod.FORMS;  // Set the "enum" value we want to use.
var methodName = authenticationMethodVariable.ToString();       // Get the user-friendly "name" of the "enum" value.

// Perform logic based on which "enum" value was chosen.
switch (authenticationMethodVariable.Value)
{
    case authenticationMethodVariable.Values.Forms: // Do something
        break;
    case authenticationMethodVariable.Values.Windows: // Do something
        break;
    case authenticationMethodVariable.Values.SSN: // Do something
        break;      
}

කෙටි විසඳුමක් වනුයේ enums ඉවත් කිරීම}} ඒ වෙනුවට ඔබ විසින් ඉදිකරන ලද එනූම් ගණන කොපමණ දැයි ස්ථිතික ගණනය කිරීමකි. මෙය ඔබ එනූම් ලැයිස්තුවට නව අවස්ථාවක් එක් කිරීමට අවශ්‍ය නොවන ප්‍රතිලාභයක් ද ලබා දෙයි. උදා: public static int nextAvailable { get; private set; }පසුව ඉදිකිරීම්කරු තුළthis.Value = nextAvailable++;
kjhf

සිත්ගන්නා අදහස @kjhf. මගේ කනස්සල්ල වනුයේ යමෙකු කේතය නැවත සකසන්නේ නම්, එනුම් අගයන්ට පවරා ඇති අගය ද වෙනස් විය හැකිය. උදාහරණයක් ලෙස, ගොනුවකට / දත්ත ගබඩාවකට එනුම් අගය සුරකින විට වැරදි එනුම් අගය ලබා ගැනීමට මෙය හේතු විය හැක, “නව සත්‍යාපන ක්‍රමය (...)” රේඛාවල අනුපිළිවෙල වෙනස් වේ (උදා: එකක් ඉවත් කරනු ලැබේ), ඉන්පසු යෙදුම නැවත ධාවනය කර ගොනුවෙන් / දත්ත ගබඩාවෙන් එනූම් අගය ලබා ගැනීම; මුලින් සුරකින ලද සත්‍යාපන ක්‍රමයට enum අගය නොගැලපේ.
මාරාන්තික

හොඳ කරුණක් - මෙම විශේෂිත අවස්ථාවන්හිදී මිනිසුන් එනුම්ගේ පූර්ණ සංඛ්‍යා අගය මත රඳා නොසිටිනු ඇතැයි මම විශ්වාස කරමි. GetHashCode (). සැලකිලිමත් වන්නේ නම්, ඔබට සැමවිටම "DO NOT REORDER" සමඟ විශාල අදහසක් ඉදිරිපත් කළ හැකිය: p
kjhf

=වැඩ කිරීමට මාරුවීමට ඔබට ක්‍රියාකරුට අධික ලෙස පැටවිය නොහැකිද? මම මෙය VB වලින් කළ අතර දැන් එය select caseප්‍රකාශයක් ලෙස භාවිතා කළ හැකිය .
user1318499

@ user1318499 නැත, C # ට VB ට වඩා ස්විච් ප්‍රකාශය වටා දැඩි නීති ඇත. සිද්ධි ප්‍රකාශය සඳහා ඔබට පන්ති අවස්ථා භාවිතා කළ නොහැක; ඔබට භාවිතා කළ හැක්කේ නියත ප්‍රාථමිකයන් පමණි.
මාරාන්තික

13

මම ඉහත යෝජනා කිහිපයක එකතුවක් භාවිතා කරමි. දැන්, මම අන්තර්ජාලයේ කොතැනක හෝ සොයාගත් යම් කේතයකින් අදහස ලබා ගත්තෙමි, නමුත් මට එය ලැබුනේ කොහෙන්දැයි හෝ එය සොයා ගැනීමට මට මතක නැත. එබැවින් යමෙකු සමාන පෙනුමක් ඇති දෙයක් සොයාගතහොත් කරුණාකර ආරෝපණය සමඟ අදහස් දක්වන්න.

කෙසේ වෙතත්, භාවිතයට වර්ග පරිවර්තකයන් සම්බන්ධ වේ, එබැවින් ඔබ UI සමඟ බැඳී සිටින්නේ නම් එය 'ක්‍රියාත්මක වේ'. වර්ග පරිවර්තකයේ සිට ස්ථිතික ක්‍රම වෙත ආරම්භ කිරීමෙන් ඔබට ඉක්මන් කේත සෙවීම සඳහා ජකුබ්ගේ රටාව සමඟ දිගු කළ හැකිය.

මූලික භාවිතය මේ වගේ ය

[TypeConverter(typeof(CustomEnumTypeConverter<MyEnum>))]
public enum MyEnum
{
    // The custom type converter will use the description attribute
    [Description("A custom description")]
    ValueWithCustomDescription,

   // This will be exposed exactly.
   Exact
}

අභිරුචි එනුම් වර්ගයේ පරිවර්තකය සඳහා කේතය පහත පරිදි වේ:

public class CustomEnumTypeConverter<T> : EnumConverter
    where T : struct
{
    private static readonly Dictionary<T,string> s_toString = 
      new Dictionary<T, string>();

    private static readonly Dictionary<string, T> s_toValue = 
      new Dictionary<string, T>();

    private static bool s_isInitialized;

    static CustomEnumTypeConverter()
    {
        System.Diagnostics.Debug.Assert(typeof(T).IsEnum,
          "The custom enum class must be used with an enum type.");
    }

    public CustomEnumTypeConverter() : base(typeof(T))
    {
        if (!s_isInitialized)
        {
            Initialize();
            s_isInitialized = true;
        }
    }

    protected void Initialize()
    {
        foreach (T item in Enum.GetValues(typeof(T)))
        {
            string description = GetDescription(item);
            s_toString[item] = description;
            s_toValue[description] = item;
        }
    }

    private static string GetDescription(T optionValue)
    {
        var optionDescription = optionValue.ToString();
        var optionInfo = typeof(T).GetField(optionDescription);
        if (Attribute.IsDefined(optionInfo, typeof(DescriptionAttribute)))
        {
            var attribute = 
              (DescriptionAttribute)Attribute.
                 GetCustomAttribute(optionInfo, typeof(DescriptionAttribute));
            return attribute.Description;
        }
        return optionDescription;
    }

    public override object ConvertTo(ITypeDescriptorContext context, 
       System.Globalization.CultureInfo culture, 
       object value, Type destinationType)
    {
        var optionValue = (T)value;

        if (destinationType == typeof(string) && 
            s_toString.ContainsKey(optionValue))
        {
            return s_toString[optionValue];
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, 
       System.Globalization.CultureInfo culture, object value)
    {
        var stringValue = value as string;

        if (!string.IsNullOrEmpty(stringValue) && s_toValue.ContainsKey(stringValue))
        {
            return s_toValue[stringValue];
        }

        return base.ConvertFrom(context, culture, value);
    }
}

}


එය භාවිතා කරන්නේ කෙසේද? ස්තූතියි. උදා: MyEnum.ValueWithCustomDescription.??()හෝ යමක්?
Trương Quốc Khánh

මෙම පිළිතුර දශකයකට පමණ පෙර ලියා ඇති බැවින් මුල් සන්දර්භය ගැන මට විශ්වාස නැත. SO සමඟ ඇති ගැටළුව නම් එය සදහටම පැවතීමයි. වින්ෆෝම්ස් හෝ ඩබ්ලිව්පීඑෆ් වැනි යූඅයි වල පෙන්විය යුතු දත්ත එකතු කිරීම සම්බන්ධව මෙය සිදු වූ බව මම විශ්වාස කරමි, එවැනි අවස්ථාවකදී දේපල හෝ එකතු කිරීම යූඅයි පාලනයට බැඳ තැබීමෙන් වර්ගය පරිවර්තකය කෙලින්ම ලබා ගනී.
ස්ටීව් මිචම්

12

ඔබේ ප්‍රශ්නයේදී ඔබ කිසි විටෙකත් එනුම් වල සංඛ්‍යාත්මක අගය අවශ්‍ය යැයි කීවේ නැත.

ඔබට අවශ්‍ය නම් සහ එනුම් වර්ගයේ නූල් අවශ්‍ය නම් (එය අත්‍යවශ්‍ය වර්ගයක් නොවන බැවින් එනුම් පදනමක් විය නොහැක) මෙහි ක්‍රමයක් ඇත:

    static class AuthenticationMethod
    {
        public static readonly string
            FORMS = "Forms",
            WINDOWSAUTHENTICATION = "WindowsAuthentication";
    }

ඔබට එය යොමු කිරීම සඳහා එනුම් ලෙස එකම සින්ටැක්ස් භාවිතා කළ හැකිය

if (bla == AuthenticationMethod.FORMS)

එය සංඛ්‍යාත්මක අගයන්ට වඩා ටිකක් මන්දගාමී වනු ඇත (සංඛ්‍යා වෙනුවට නූල් සංසන්දනය කිරීම) නමුත් ප්ලස් පැත්තේ එය නූලට ප්‍රවේශ වීමට පරාවර්තනය (මන්දගාමී) භාවිතා නොකරයි.


ඔබ "ස්ථිතික කියවීමට පමණක්" වෙනුවට "const" භාවිතා කරන්නේ නම්, එවිට ඔබට ස්විච් ප්‍රකාශයක අගයන් සිද්ධි ලේබල් ලෙස භාවිතා කළ හැකිය.
එඩ් එන්

11

ව්‍යාප්ති ක්‍රමයක් ලෙස මම මෙය විසඳූ ආකාරය:

using System.ComponentModel;
public static string GetDescription(this Enum value)
{
    var descriptionAttribute = (DescriptionAttribute)value.GetType()
        .GetField(value.ToString())
        .GetCustomAttributes(false)
        .Where(a => a is DescriptionAttribute)
        .FirstOrDefault();

    return descriptionAttribute != null ? descriptionAttribute.Description : value.ToString();
}

එනුම්:

public enum OrderType
{
    None = 0,
    [Description("New Card")]
    NewCard = 1,
    [Description("Reload")]
    Refill = 2
}

භාවිතය (මෙහි o.OrderType යනු එනූම් හා සමාන නමක් ඇති දේපලකි):

o.OrderType.GetDescription()

එමඟින් මට සත්‍ය කාඩ්පත් අගය වන නිව්කාඩ් සහ නැවත පිරවීම වෙනුවට “නව කාඩ්” හෝ “රීලෝඩ්” මාලාවක් ලබා දේ.


සම්පූර්ණත්වය සඳහා ඔබේ විස්තරය පන්තියේ පිටපතක් ඇතුළත් කළ යුතුය.
බර්නි වයිට්

3
බර්නි, DescriptionAttribute System.ComponentModel
agentnega

11

යාවත්කාලීන කිරීම: මෙම පිටුවට පිවිසීමෙන්, වසර 8 කට පසුව, C # ස්පර්ශ නොකිරීමෙන් පසුව, මගේ පිළිතුර තවදුරටත් හොඳම විසඳුම නොවන බව පෙනේ. ගුණාංග-ශ්‍රිත සමඟ බැඳී ඇති පරිවර්තක විසඳුමට මම ඇත්තෙන්ම කැමතියි.

ඔබ මෙය කියවන්නේ නම්, කරුණාකර ඔබ වෙනත් පිළිතුරු ද පරීක්ෂා කර බැලීමට වග බලා ගන්න.
(ඉඟිය: ඒවා මෙයට ඉහළින්)


ඔබ බොහෝ දෙනා ලෙස, ජකුබ් එටුර්ක් විසින් තෝරාගත් පිළිතුරට මම ඇත්තෙන්ම කැමතියි , නමුත් මමද පිටපත්-පේස්ට් කේතය පිළිකුල් කරමි, මට හැකි පමණින් එය කිරීමට උත්සාහ කරමි.

ඒ නිසා මම තීරණය කළා මට බොහෝ ක්‍රියාකාරකම් උරුම වී ඇති / ගොඩනංවන ලද එනුම්බේස් පන්තියක් අවශ්‍ය බවත්, හැසිරීම වෙනුවට අන්තර්ගතය කෙරෙහි අවධානය යොමු කිරීමට මට ඉඩ දෙන බවත්.

මෙම ප්‍රවේශයේ ඇති ප්‍රධාන ගැටළුව පදනම් වී ඇත්තේ එනුම් අගයන් ටයිප්-ආරක්ෂිත අවස්ථාවන් වුවද, අන්තර්ක්‍රියාකාරිත්වය එනුම් පන්තියේ වර්ගය ස්ථිතික ලෙස ක්‍රියාත්මක කිරීම සමඟ ය. ඉතින් ජනක මැජික් වල කුඩා උදව්වෙන්, මම හිතන්නේ අවසානයේ මට නිවැරදි මිශ්‍රණයක් ලැබුණා. මම කළා වගේ කවුරුහරි මෙය ප්‍රයෝජනවත් වේ යැයි සිතමි.

මම ජකුබ්ගේ ආදර්ශයෙන් ආරම්භ කරමි, නමුත් උරුමය සහ ජනකතා භාවිතා කරමින්:

public sealed class AuthenticationMethod : EnumBase<AuthenticationMethod, int>
{
    public static readonly AuthenticationMethod FORMS =
        new AuthenticationMethod(1, "FORMS");
    public static readonly AuthenticationMethod WINDOWSAUTHENTICATION =
        new AuthenticationMethod(2, "WINDOWS");
    public static readonly AuthenticationMethod SINGLESIGNON =
        new AuthenticationMethod(3, "SSN");

    private AuthenticationMethod(int Value, String Name)
        : base( Value, Name ) { }
    public new static IEnumerable<AuthenticationMethod> All
    { get { return EnumBase<AuthenticationMethod, int>.All; } }
    public static explicit operator AuthenticationMethod(string str)
    { return Parse(str); }
}

මෙන්න මූලික පන්තිය:

using System;
using System.Collections.Generic;
using System.Linq; // for the .AsEnumerable() method call

// E is the derived type-safe-enum class
// - this allows all static members to be truly unique to the specific
//   derived class
public class EnumBase<E, T> where E: EnumBase<E, T>
{
    #region Instance code
    public T Value { get; private set; }
    public string Name { get; private set; }

    protected EnumBase(T EnumValue, string Name)
    {
        Value = EnumValue;
        this.Name = Name;
        mapping.Add(Name, this);
    }

    public override string ToString() { return Name; }
    #endregion

    #region Static tools
    static private readonly Dictionary<string, EnumBase<E, T>> mapping;
    static EnumBase() { mapping = new Dictionary<string, EnumBase<E, T>>(); }
    protected static E Parse(string name)
    {
        EnumBase<E, T> result;
        if (mapping.TryGetValue(name, out result))
        {
            return (E)result;
        }

        throw new InvalidCastException();
    }
    // This is protected to force the child class to expose it's own static
    // method.
    // By recreating this static method at the derived class, static
    // initialization will be explicit, promising the mapping dictionary
    // will never be empty when this method is called.
    protected static IEnumerable<E> All
    { get { return mapping.Values.AsEnumerable().Cast<E>(); } }
    #endregion
}

මූලික ස්ථිතික ඉදිකිරීම්කරු වෙතින් ව්‍යුත්පන්න කළ ස්ථිතික ඉදිකිරීම්කරු ඇමතීමට ඔබට හැකිය. මම තවමත් ඒ ගැන සොයා බලමින් සිටිමි, නමුත් මෙතෙක් මට එහි කිසිදු ගැටළුවක් හමු නොවීය: stackoverflow.com/questions/55290034/…
Cory-G

10

මම කීත් සමඟ එකඟයි, නමුත් මට ඡන්දය ප්‍රකාශ කළ නොහැක (තවමත්).

මට අවශ්‍ය දේ හරියටම ලබා දීමට මම ස්ථිතික ක්‍රමයක් සහ ස්විච් ප්‍රකාශයක් භාවිතා කරමි. දත්ත සමුදාය තුළ මම ඉතා කුඩා ප්‍රමාණයක් ගබඩා කරන අතර මගේ කේතය භාවිතා කරන්නේ සත්‍ය එනුම් පමණි, එබැවින් නූල් UI අවශ්‍යතා සඳහා වේ. බොහෝ පරීක්ෂණ වලින් පසු මෙය හොඳම කාර්ය සාධනය සහ ප්‍රතිදානය පාලනය කිරීමට හේතු විය.

public static string ToSimpleString(this enum)
{
     switch (enum)
     {
         case ComplexForms:
             return "ComplexForms";
             break;
     }
}

public static string ToFormattedString(this enum)
{
     switch (enum)
     {
         case ComplexForms:
             return "Complex Forms";
             break;
     }
}

කෙසේ වෙතත්, සමහර ගිණුම් වලට අනුව, මෙය නඩත්තු කළ හැකි බියකරු සිහිනයක් හා කේත සුවඳක් ඇති කරයි. දිගු හා බොහෝ එනූම් හෝ නිතර වෙනස් වන එනූම් ගැන විමසිල්ලෙන් සිටීමට මම උත්සාහ කරමි. එසේ නොමැතිනම් මෙය මට හොඳ විසඳුමක් වී තිබේ.


10

ඔබ මෙහි පැමිණියේ සරල "එනූම්" එකක් ක්‍රියාවට නැංවීමට නම්, නමුත් එහි අගයන් තීන්ත වෙනුවට නූල් නම්, මෙන්න සරලම විසඳුම:

    public sealed class MetricValueList
    {
        public static readonly string Brand = "A4082457-D467-E111-98DC-0026B9010912";
        public static readonly string Name = "B5B5E167-D467-E111-98DC-0026B9010912";
    }

ක්‍රියාත්මක කිරීම:

var someStringVariable = MetricValueList.Brand;

2
භාවිතා කිරීම වෙනුවට විචල්යයන් සෑදීම වඩා හොඳය static readonly.
ඇන්ඩිජීක්

1
පොදු වේලාවට ප්‍රවේශ විය හැකි පංති සඳහා කොන්ස්ට් හොඳ නැත, ඒවා සම්පාදනය කරන වේලාවේදී පුළුස්සා ඇති බැවින්, ඔබේ සම්පූර්ණ කේතය නැවත සංයුක්ත කිරීමකින් තොරව තෙවන පාර්ශවීය ඩීඑල්එල් වෙනුවට ආදේශ කළ නොහැක.
ක්‍රිස්ටියන් විලියම්ස්

7

මම මෙම ගැටලුවට මුහුණ දෙන විට, පළමුවෙන් පිළිතුරු සෙවීමට මම උත්සාහ කරන ප්‍රශ්න කිහිපයක් තිබේ:

  • මගේ එනූම් අගයන්හි නම් මේ සඳහා ප්‍රමාණවත් තරම් මිත්‍රශීලීද, නැතහොත් මට මිත්‍රශීලී ඒවා සැපයිය යුතුද?
  • මට සංචාරය කිරීමට අවශ්‍යද? එනම්, මට පෙළ අගයන් ගෙන ඒවා enum අගයන් ලෙස විග්‍රහ කිරීමට අවශ්‍ය වේද?
  • මෙය මගේ ව්‍යාපෘතියේ බොහෝ එනමුත් සඳහා කළ යුතු දෙයක්ද, නැතිනම් එකක්ද?
  • මම මෙම තොරතුරු ඉදිරිපත් කරන්නේ කුමන ආකාරයේ UI අංගයන්ද - විශේෂයෙන් මම UI සමඟ බැඳී සිටිනවාද, නැතහොත් දේපල පත්‍ර භාවිතා කරන්නේද?
  • මෙය දේශීයකරණය කළ යුතුද?

මෙය කළ හැකි සරලම ක්‍රමය වන්නේ Enum.GetValue(සහ වටකුරු කැපීම සඳහා සහාය වීමයි Enum.Parse). TypeConverterස්ටීව් මිචම් යෝජනා කරන පරිදි, UI බන්ධනයට සහය දැක්වීම සඳහා එය ගොඩ නැගීම ද බොහෝ විට වටී . (A ගොඩනැගීම අවශ්‍ය නොවේTypeConverter ඔබ දේපල පත්‍ර භාවිතා විට දේපල පත්‍ර පිළිබඳ හොඳ දෙයකි. ස්වාමියා දන්නා නමුත් ඔවුන්ට ඔවුන්ගේම ගැටළු තිබේ.)

පොදුවේ ගත් කල, ඉහත ප්‍රශ්නවලට පිළිතුරු මඟින් එය ක්‍රියාත්මක නොවන බව යෝජනා කරන්නේ නම්, මගේ ඊළඟ පියවර වන්නේ ස්ථිතිකයක් නිර්මාණය කිරීම සහ ජනගහනය Dictionary<MyEnum, string>කිරීමයි Dictionary<Type, Dictionary<int, string>>. මම අතරමැදි සැරසිලි-කේත-ගුණාංග සහිත පියවර මඟ හැරීමට නැඹුරු වෙමි, මන්ද සාමාන්‍යයෙන් ඊළඟට පයික් එකෙන් පහළට එන්නේ යෙදවීමෙන් පසු මිත්‍රශීලී අගයන් වෙනස් කිරීමේ අවශ්‍යතාවයයි (බොහෝ විට, නමුත් සෑම විටම නොවේ, ප්‍රාදේශීයකරණය නිසා).


7

පහත සඳහන් පෝස්ටයට අදහස් දැක්වීමක් ලෙස මෙය පළ කිරීමට මට අවශ්‍ය වූ නමුත් මට ප්‍රමාණවත් නියෝජිතයෙකු නොමැති නිසා එය කළ නොහැකි විය - එබැවින් කරුණාකර ඡන්දය ප්‍රකාශ නොකරන්න. කේතයේ දෝෂයක් ඇති අතර මෙම විසඳුම භාවිතා කිරීමට උත්සාහ කරන පුද්ගලයින්ට මෙය පෙන්වා දීමට මට අවශ්‍ය විය:

[TypeConverter(typeof(CustomEnumTypeConverter(typeof(MyEnum))]
public enum MyEnum
{
  // The custom type converter will use the description attribute
  [Description("A custom description")]
  ValueWithCustomDescription,
  // This will be exposed exactly.
  Exact
}

විය යුතුයි

[TypeConverter(typeof(CustomEnumTypeConverter<MyEnum>))]
public enum MyEnum
{
  // The custom type converter will use the description attribute
  [Description("A custom description")]
  ValueWithCustomDescription,

  // This will be exposed exactly.
  Exact
}

දීප්තිමත්!


5

මගේ ප්‍රභේදය

public struct Colors
{
    private String current;

    private static string red = "#ff0000";
    private static string green = "#00ff00";
    private static string blue = "#0000ff";

    private static IList<String> possibleColors; 

    public static Colors Red { get { return (Colors) red; } }
    public static Colors Green { get { return (Colors) green; } }
    public static Colors Blue { get { return (Colors) blue; } }

    static Colors()
    {
        possibleColors = new List<string>() {red, green, blue};
    }

    public static explicit operator String(Colors value)
    {
        return value.current;
    }

    public static explicit operator Colors(String value)
    {
        if (!possibleColors.Contains(value))
        {
            throw new InvalidCastException();
        }

        Colors color = new Colors();
        color.current = value;
        return color;
    }

    public static bool operator ==(Colors left, Colors right)
    {
        return left.current == right.current;
    }

    public static bool operator !=(Colors left, Colors right)
    {
        return left.current != right.current;
    }

    public bool Equals(Colors other)
    {
        return Equals(other.current, current);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (obj.GetType() != typeof(Colors)) return false;
        return Equals((Colors)obj);
    }

    public override int GetHashCode()
    {
        return (current != null ? current.GetHashCode() : 0);
    }

    public override string ToString()
    {
        return current;
    }
}

කේතය ටිකක් කැත ලෙස පෙනේ, නමුත් මෙම ව්‍යුහයේ භාවිතයන් බෙහෙවින් ඉදිරිපත් කරයි.

Colors color1 = Colors.Red;
Console.WriteLine(color1); // #ff0000

Colors color2 = (Colors) "#00ff00";
Console.WriteLine(color2); // #00ff00

// Colors color3 = "#0000ff"; // Compilation error
// String color4 = Colors.Red; // Compilation error

Colors color5 = (Colors)"#ff0000";
Console.WriteLine(color1 == color5); // True

Colors color6 = (Colors)"#00ff00";
Console.WriteLine(color1 == color6); // False

එසේම, මම සිතන්නේ, එවැනි එනුම් විශාල ප්‍රමාණයක් අවශ්‍ය නම්, කේත උත්පාදනය (උදා: T4) භාවිතා කළ හැකිය.


4

විකල්ප 1:

public sealed class FormsAuth
{
     public override string ToString{return "Forms Authtentication";}
}
public sealed class WindowsAuth
{
     public override string ToString{return "Windows Authtentication";}
}

public sealed class SsoAuth
{
     public override string ToString{return "SSO";}
}

ඊළගට

object auth = new SsoAuth(); //or whatever

//...
//...
// blablabla

DoSomethingWithTheAuth(auth.ToString());

විකල්ප 2:

public enum AuthenticationMethod
{
        FORMS = 1,
        WINDOWSAUTHENTICATION = 2,
        SINGLESIGNON = 3
}

public class MyClass
{
    private Dictionary<AuthenticationMethod, String> map = new Dictionary<AuthenticationMethod, String>();
    public MyClass()
    {
         map.Add(AuthenticationMethod.FORMS,"Forms Authentication");
         map.Add(AuthenticationMethod.WINDOWSAUTHENTICATION ,"Windows Authentication");
         map.Add(AuthenticationMethod.SINGLESIGNON ,"SSo Authentication");
    }
}

4

අපි විසඳීමට උත්සාහ කරන ගැටලුව ගැන ඔබ සිතන්නේ නම්, එය අපට කිසිසේත්ම අවශ්‍ය නොවන එන්යූම් එකක් නොවේ. එකිනෙකා සමඟ නිශ්චිත අගයන් සංඛ්‍යාවක් සම්බන්ධ කිරීමට ඉඩ දෙන වස්තුවක් අපට අවශ්‍යය; වෙනත් වචන වලින් කිවහොත්, පන්තියක් අර්ථ දැක්වීම සඳහා.

මා මෙහි දකින හොඳම විකල්පය වන්නේ ජකුබ් එටුර්ක්ගේ වර්ගය-ආරක්ෂිත එනුම් රටාවයි.

එය දෙස බලන්න:

  • එයට පුද්ගලික ඉදිකිරීම්කරුවෙකු සිටින බැවින් අවසර ලත් අගයන් අර්ථ දැක්විය හැක්කේ පන්තියට පමණි.
  • එය මුද්‍රා තැබූ පන්තියක් බැවින් උරුමයෙන් වටිනාකම් වෙනස් කළ නොහැක.
  • එය ටයිප්-ආරක්ෂිත වන අතර, ඔබේ ක්‍රමවලට එම වර්ගය පමණක් අවශ්‍ය වේ.
  • අගයන් වෙත ප්‍රවේශ වීමෙන් කිසිදු පරාවර්තන කාර්ය සාධනයක් නොමැත.
  • අවසාන වශයෙන්, ක්ෂේත්‍ර දෙකකට වඩා එකට සම්බන්ධ කිරීම සඳහා එය වෙනස් කළ හැකිය, උදාහරණයක් ලෙස නමක්, විස්තරයක් සහ සංඛ්‍යාත්මක අගයක්.

4

මට නම්, ප්‍රායෝගික ප්‍රවේශය පන්තිය තුළ පන්තියයි, නියැදිය:

public class MSEModel
{
    class WITS
    {
        public const string DATE = "5005";
        public const string TIME = "5006";
        public const string MD = "5008";
        public const string ROP = "5075";
        public const string WOB = "5073";
        public const string RPM = "7001";
... 
    }

4

.NET හි නූල්-වටිනා එනුම් නිර්මාණය කිරීම සඳහා මම මූලික පන්තියක් නිර්මාණය කළෙමි. එය ඔබේ ව්‍යාපෘති වලට පිටපත් කර ඇලවිය හැකි එක් C # ගොනුවක් පමණි, නැතහොත් StringEnum නම් නුජෙට් පැකේජය හරහා ස්ථාපනය කරන්න . GitHub Repo

  • Xml විවරණය සමඟ පන්තිය විවරණය කර ඇත්නම් ඉන්ටෙලිසෙන්ස් විසින් එනුම් නාමය යෝජනා කරනු ඇත <completitionlist>. (C # සහ VB යන දෙකින්ම ක්‍රියා කරයි)

Intellisense Demo

  • සාමාන්‍ය එනූමයකට සමාන භාවිතය:
///<completionlist cref="HexColor"/> 
class HexColor : StringEnum<HexColor>
{
    public static readonly HexColor Blue = Create("#FF0000");
    public static readonly HexColor Green = Create("#00FF00");
    public static readonly HexColor Red = Create("#000FF");
}
    // Static Parse Method
    HexColor.Parse("#FF0000") // => HexColor.Red
    HexColor.Parse("#ff0000", caseSensitive: false) // => HexColor.Red
    HexColor.Parse("invalid") // => throws InvalidOperationException

    // Static TryParse method.
    HexColor.TryParse("#FF0000") // => HexColor.Red
    HexColor.TryParse("#ff0000", caseSensitive: false) // => HexColor.Red
    HexColor.TryParse("invalid") // => null

    // Parse and TryParse returns the preexistent instances
    object.ReferenceEquals(HexColor.Parse("#FF0000"), HexColor.Red) // => true

    // Conversion from your `StringEnum` to `string`
    string myString1 = HexColor.Red.ToString(); // => "#FF0000"
    string myString2 = HexColor.Red; // => "#FF0000" (implicit cast)

ස්ථාපනය:

  • ඔබේ ව්‍යාපෘතියට පහත දැක්වෙන StringEnum පාදක පන්තිය අලවන්න. ( නවතම අනුවාදය )
  • නැතහොත් StringEnum NuGet පැකේජය ස්ථාපනය කරන්න , එය පදනම් වී ඇති .Net Standard 1.0බැවින් එය .Net Core> = 1.0, .Net Framework> = 4.5, Mono> = 4.6, ආදිය මත ක්‍රියාත්මක වේ.
    /// <summary>
    /// Base class for creating string-valued enums in .NET.<br/>
    /// Provides static Parse() and TryParse() methods and implicit cast to string.
    /// </summary>
    /// <example> 
    /// <code>
    /// class Color : StringEnum &lt;Color&gt;
    /// {
    ///     public static readonly Color Blue = Create("Blue");
    ///     public static readonly Color Red = Create("Red");
    ///     public static readonly Color Green = Create("Green");
    /// }
    /// </code>
    /// </example>
    /// <typeparam name="T">The string-valued enum type. (i.e. class Color : StringEnum&lt;Color&gt;)</typeparam>
    public abstract class StringEnum<T> : IEquatable<T> where T : StringEnum<T>, new()
    {
        protected string Value;
        private static Dictionary<string, T> valueDict = new Dictionary<string, T>();
        protected static T Create(string value)
        {
            if (value == null)
                return null; // the null-valued instance is null.

            var result = new T() { Value = value };
            valueDict.Add(value, result);
            return result;
        }

        public static implicit operator string(StringEnum<T> enumValue) => enumValue.Value;
        public override string ToString() => Value;

        public static bool operator !=(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value != o2?.Value;
        public static bool operator ==(StringEnum<T> o1, StringEnum<T> o2) => o1?.Value == o2?.Value;

        public override bool Equals(object other) => this.Value.Equals((other as T)?.Value ?? (other as string));
        bool IEquatable<T>.Equals(T other) => this.Value.Equals(other.Value);
        public override int GetHashCode() => Value.GetHashCode();

        /// <summary>
        /// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else throws InvalidOperationException.
        /// </summary>
        /// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
        /// <param name="caseSensitive">If true, the strings must match case and takes O(log n). False allows different case but is little bit slower (O(n))</param>
        public static T Parse(string value, bool caseSensitive = true)
        {
            var result = TryParse(value, caseSensitive);
            if (result == null)
                throw new InvalidOperationException((value == null ? "null" : $"'{value}'") + $" is not a valid {typeof(T).Name}");

            return result;
        }

        /// <summary>
        /// Parse the <paramref name="value"/> specified and returns a valid <typeparamref name="T"/> or else returns null.
        /// </summary>
        /// <param name="value">The string value representad by an instance of <typeparamref name="T"/>. Matches by string value, not by the member name.</param>
        /// <param name="caseSensitive">If true, the strings must match case. False allows different case but is slower: O(n)</param>
        public static T TryParse(string value, bool caseSensitive = true)
        {
            if (value == null) return null;
            if (valueDict.Count == 0) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // force static fields initialization
            if (caseSensitive)
            {
                if (valueDict.TryGetValue(value, out T item))
                    return item;
                else
                    return null;
            }
            else
            {
                // slower O(n) case insensitive search
                return valueDict.FirstOrDefault(f => f.Key.Equals(value, StringComparison.OrdinalIgnoreCase)).Value;
                // Why Ordinal? => https://esmithy.net/2007/10/15/why-stringcomparisonordinal-is-usually-the-right-choice/
            }
        }
    }

3

එනූම්ස් සමඟ නූල් ඇසුරු කිරීමේ කාර්යය ඉටු කිරීමට තවත් ක්‍රමයක් මෙන්න:

struct DATABASE {
    public enum enums {NOTCONNECTED, CONNECTED, ERROR}
    static List<string> strings =
        new List<string>() {"Not Connected", "Connected", "Error"};

    public string GetString(DATABASE.enums value) {
        return strings[(int)value];
    }
}

මෙම ක්‍රමය මේ ආකාරයට හැඳින්වේ:

public FormMain() {
    DATABASE dbEnum;

    string enumName = dbEnum.GetString(DATABASE.enums.NOTCONNECTED);
}

ඔබට ආශ්‍රිත enums ඔවුන්ගේ ව්‍යුහය තුළ කාණ්ඩගත කළ හැකිය. මෙම ක්‍රමය enum වර්ගය භාවිතා කරන බැවින්, සෑදීමේදී ඔබට enums ලැයිස්තුව පෙන්වීමට Intellisense භාවිතා කළ හැකියGetString() ඇමතුම ලබා .

ඔබට විකල්පයක් ලෙස DATABASEstruct හි නව ක්‍රියාකරු භාවිතා කළ හැකිය . එය භාවිතා Listනොකිරීම යන්නෙන් අදහස් වන්නේ පළමු GetString()ඇමතුම ලැබෙන තුරු නූල් වෙන් නොකිරීමයි .


3

මෙහි විශාල පිළිතුරු රාශියක් ඇති නමුත් මගේ නඩුවේදී මට අවශ්‍ය දේ “නූල් එනුම්” වලින් විසඳා ගත නොහැකි විය.

  1. ස්විච් ප්‍රකාශයක භාවිතා කළ හැකිය උදා: ස්විචය (myEnum)
  2. ක්‍රියාකාරී පරාමිතීන් සඳහා භාවිතා කළ හැකිය උදා: foo (myEnum වර්ගය)
  3. යොමු දැක්විය හැක උදා. MyEnum.FirstElement
  4. මට නූල් භාවිතා කළ හැකිය උදා: foo ("FirstElement") == foo (myEnum.FirstElement)

1,2 සහ 4 සැබවින්ම සී # ටයිප්ඩෙෆ් නූලකින් විසඳිය හැකිය (නූල් සී # වලින් මාරු කළ හැකි බැවින්)

3 ස්ථිතික කොන්ස්ට් නූල් මගින් විසඳිය හැකිය. එබැවින් ඔබට එකම අවශ්‍යතා තිබේ නම්, මෙය සරලම ප්‍රවේශයයි:

public sealed class Types
{

    private readonly String name;

    private Types(String name)
    {
        this.name = name;

    }

    public override String ToString()
    {
        return name;
    }

    public static implicit operator Types(string str)
    {
        return new Types(str);

    }
    public static implicit operator string(Types str)
    {
        return str.ToString();
    }


    #region enum

    public const string DataType = "Data";
    public const string ImageType = "Image";
    public const string Folder = "Folder";
    #endregion

}

මෙය උදාහරණයක් ලෙස ඉඩ දෙයි:

    public TypeArgs(Types SelectedType)
    {
        Types SelectedType = SelectedType
    }

සහ

public TypeObject CreateType(Types type)
    {
        switch (type)
        {

            case Types.ImageType:
              //
                break;

            case Types.DataType:
             //
                break;

        }
    }

CreateType නූලකින් හෝ වර්ගයකින් හැඳින්විය හැක. කෙසේ වෙතත් අවාසිය නම් ඕනෑම නූලක් ස්වයංක්‍රීයව වලංගු එනමම් වීමයි වන අතර මෙය වෙනස් කළ හැකි නමුත් පසුව එයට යම් ආකාරයක ආරම්භක ශ්‍රිතයක් අවශ්‍ය වනු ඇත ... එසේත් නැතිනම් ඒවා අභ්‍යන්තරව පැහැදිලි ලෙස ඉදිරිපත් කළ හැකිද?

දැන් int අගය (සමහර විට සාපේක්ෂව වේගය සඳහා) ඔබට වැදගත් නම්, ඔබ හැකි Jakub Šturc අතිශය අසාමාන්ය පිළිතුර සිට යම් අදහස් භාවිතා සහ යමක් ටිකක් පිස්සු, ඒක මගේ මෙය ආරම්භ වේ:

    public sealed class Types
{
    private static readonly Dictionary<string, Types> strInstance = new Dictionary<string, Types>();
    private static readonly Dictionary<int, Types> intInstance = new Dictionary<int, Types>();

    private readonly String name;
    private static int layerTypeCount = 0;
    private int value;
    private Types(String name)
    {
        this.name = name;
        value = layerTypeCount++;
        strInstance[name] = this;
        intInstance[value] = this;
    }

    public override String ToString()
    {
        return name;
    }


    public static implicit operator Types(int val)
    {
        Types result;
        if (intInstance.TryGetValue(val, out result))
            return result;
        else
            throw new InvalidCastException();
    }

    public static implicit operator Types(string str)
    {
        Types result;
        if (strInstance.TryGetValue(str, out result))
        {
            return result;
        }
        else
        {
            result = new Types(str);
            return result;
        }

    }
    public static implicit operator string(Types str)
    {
        return str.ToString();
    }

    public static bool operator ==(Types a, Types b)
    {
        return a.value == b.value;
    }
    public static bool operator !=(Types a, Types b)
    {
        return a.value != b.value;
    }

    #region enum

    public const string DataType = "Data";
    public const string ImageType = "Image";

    #endregion

}

නමුත් ඇත්ත වශයෙන්ම "වර්ග බොබ් = 4;" ඔබ ඒවා මුලින් ආරම්භ නොකළේ නම් එය අර්ථ විරහිත වනු ඇත.

නමුත් න්‍යාය අනුව TypeA == TypeB ඉක්මන් වනු ඇත ...


3

මම ඔබව නිවැරදිව වටහා ගන්නේ නම්, ඔබට සරලවම භාවිතා කළ හැකිය .ToString () එනුම් වල නම වටිනාකමින් ලබා ගැනීමට (එය දැනටමත් එනූම් ලෙස වාත්තු කර ඇතැයි සිතමු); ඔබට නිරුවත් int (දත්ත සමුදායකින් හෝ වෙනත් දෙයකින් කියන්නට ඉඩ තිබේ නම්) ඔබට මුලින්ම එය enum වෙත දැමිය හැකිය. පහත ක්‍රම දෙකම ඔබට එනුම් නාමය ලබා දෙනු ඇත.

AuthenticationMethod myCurrentSetting = AuthenticationMethod.FORMS;
Console.WriteLine(myCurrentSetting); // Prints: FORMS
string name = Enum.GetNames(typeof(AuthenticationMethod))[(int)myCurrentSetting-1];
Console.WriteLine(name); // Prints: FORMS

මතක තබා ගන්න, දෙවන තාක්‍ෂණය උපකල්පනය කරන්නේ ඔබ තීන්ත භාවිතා කරන අතර ඔබේ දර්ශකය 1 පදනම් (0 පදනම් නොවේ). GetNames ශ්‍රිතය සංසන්දනය කිරීමෙන් තරමක් බරයි, ඔබ එය හඳුන්වන සෑම අවස්ථාවකම සම්පූර්ණ අරාවක් ජනනය කරයි. පළමු තාක්‍ෂණයෙන් ඔබට දැකිය හැකි පරිදි .ToString () සැබවින්ම ව්‍යංගයෙන් හැඳින්වේ. මේ දෙකම දැනටමත් පිළිතුරු වල සඳහන් කර ඇත, මම උත්සාහ කරන්නේ ඔවුන් අතර ඇති වෙනස්කම් පැහැදිලි කිරීමට ය.


3

පැරණි පෝස්ට් නමුත් ...

මේ සඳහා පිළිතුර ඇත්ත වශයෙන්ම ඉතා සරල විය හැකිය. Enum.ToString () ශ්‍රිතය භාවිතා කරන්න

මෙම ශ්‍රිතයේ අධි බර 6 ක් ඇත, ඔබට නූල් අගය නැවත ලබා දීමට Enum.Tostring ("F") හෝ Enum.ToString () භාවිතා කළ හැකිය. වෙන කිසිම දෙයකට කරදර වෙන්න අවශ්‍ය නැහැ. මෙන්න වැඩ කරන නිරූපණයක්

මෙම විසඳුම සියලුම සම්පාදකයින් සඳහා ක්‍රියා නොකරනු ඇති බව සලකන්න ( මෙම නිරූපණය බලාපොරොත්තු වූ පරිදි ක්‍රියා නොකරයි ) නමුත් අවම වශයෙන් එය නවතම සම්පාදකයා සඳහා ක්‍රියා කරයි.


2

MSDN මත පදනම්ව: http://msdn.microsoft.com/en-us/library/cc138362.aspx

foreach (string str in Enum.GetNames(typeof(enumHeaderField)))
{
    Debug.WriteLine(str);
}

str යනු ක්ෂේත්‍රවල නම් වේ


3
මෙය enum හි නම ලබා දෙනු ඇත, ඔබට ඒ සඳහා ToString () ද භාවිතා කළ හැකිය, මෙය ඉල්ලූ දෙය නොවේ. ලොව පුරාවටම msdn.microsoft.com/en-us/library/system.enum.getname.aspx ඔබගේ bubu ගැන වැඩි තොරතුරු සඳහා
මිකී Perlstein

2

හොඳයි, ඉහත සියල්ලම කියවීමෙන් පසු මට හැඟෙන්නේ ගණන් කරන්නන් නූල් බවට පරිවර්තනය කිරීමේ ගැටලුව යාලුවනේ සංකීර්ණ කර ඇති බවයි. ගණනය කරන ලද ක්ෂේත්‍රවලට වඩා ගුණාංග තිබීම පිළිබඳ අදහසට මා කැමති නමුත් ගුණාංග ප්‍රධාන වශයෙන් මෙටා-දත්ත සඳහා භාවිතා කරනු ඇතැයි මම සිතමි, නමුත් ඔබේ නඩුවේදී ඔබට අවශ්‍ය වන්නේ යම් ආකාරයක ප්‍රාදේශීයකරණයක් බව මම සිතමි.

public enum Color 
{ Red = 1, Green = 2, Blue = 3}


public static EnumUtils 
{
   public static string GetEnumResourceString(object enumValue)
    {
        Type enumType = enumValue.GetType();
        string value = Enum.GetName(enumValue.GetType(), enumValue);
        string resourceKey = String.Format("{0}_{1}", enumType.Name, value);
        string result = Resources.Enums.ResourceManager.GetString(resourceKey);
        if (string.IsNullOrEmpty(result))
        {
            result = String.Format("{0}", value);
        }
        return result;
    }
}

දැන් අපි ඉහත ක්‍රමය ඇමතීමට උත්සාහ කළහොත් අපට එය මේ ආකාරයෙන් හැඳින්විය හැකිය

public void Foo()
{
  var col = Color.Red;
  Console.WriteLine (EnumUtils.GetEnumResourceString (col));
}

ඔබ කළ යුත්තේ සියලු ගණන් කිරීමේ අගයන් සහ ඊට අනුරූප නූල් අඩංගු සම්පත් ගොනුවක් සෑදීම පමණි

සම්පත් නම සම්පත් වටිනාකම
වර්ණය_ රතු පාටින් මගේ නූල් වර්ණය
වර්ණය_ නිල් බ්ලූයි
වර්ණය_ හරිත හල්ක් වර්ණය

ඇත්ත වශයෙන්ම ඒ ගැන ඉතා හොඳ දෙය නම්, ඔබේ යෙදුම දේශීයකරණය කිරීමට අවශ්‍ය නම් එය ඉතා ප්‍රයෝජනවත් වනු ඇත, මන්ද ඔබ කළ යුත්තේ ඔබේ නව භාෂාව සමඟ තවත් සම්පත් ගොනුවක් නිර්මාණය කිරීම පමණි! සහ වෝ-ලා!


1

මම එවැනි තත්වයක සිටින විට පහත විසඳුම යෝජනා කරමි.

පරිභෝජන පංතියක් ලෙස ඔබට තිබිය හැකිය

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyApp.Dictionaries
{
    class Greek
    {

        public static readonly string Alpha = "Alpha";
        public static readonly string Beta = "Beta";
        public static readonly string Gamma = "Gamma";
        public static readonly string Delta = "Delta";


        private static readonly BiDictionary<int, string> Dictionary = new BiDictionary<int, string>();


        static Greek() {
            Dictionary.Add(1, Alpha);
            Dictionary.Add(2, Beta);
            Dictionary.Add(3, Gamma);
            Dictionary.Add(4, Delta);
        }

        public static string getById(int id){
            return Dictionary.GetByFirst(id);
        }

        public static int getByValue(string value)
        {
            return Dictionary.GetBySecond(value);
        }

    }
}

ද්විපාර්ශ්වික ශබ්ද කෝෂයක් භාවිතා කිරීම: මේ මත පදනම්ව ( https://stackoverflow.com/a/255638/986160 ) යතුරු ශබ්ද කෝෂයේ තනි අගයන් සමඟ සම්බන්ධ වනු ඇතැයි උපකල්පනය කර ( https://stackoverflow.com/a / 255630/986160 ) නමුත් ටිකක් අලංකාරයි . මෙම ශබ්දකෝෂය ද ගණන් කළ නොහැකි අතර ඔබට අඟල් සිට නූල් දක්වා ඉදිරියට යා හැකිය. මෙම පංතිය හැරුණු විට ඔබේ කේත රචනයේ කිසිදු නූලක් තිබිය යුතු නොවේ.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace MyApp.Dictionaries
{

    class BiDictionary<TFirst, TSecond> : IEnumerable
    {
        IDictionary<TFirst, TSecond> firstToSecond = new Dictionary<TFirst, TSecond>();
        IDictionary<TSecond, TFirst> secondToFirst = new Dictionary<TSecond, TFirst>();

        public void Add(TFirst first, TSecond second)
        {
            firstToSecond.Add(first, second);
            secondToFirst.Add(second, first);
        }

        public TSecond this[TFirst first]
        {
            get { return GetByFirst(first); }
        }

        public TFirst this[TSecond second]
        {
            get { return GetBySecond(second); }
        }

        public TSecond GetByFirst(TFirst first)
        {
            return firstToSecond[first];
        }

        public TFirst GetBySecond(TSecond second)
        {
            return secondToFirst[second];
        }

        public IEnumerator GetEnumerator()
        {
            return GetFirstEnumerator();
        }

        public IEnumerator GetFirstEnumerator()
        {
            return firstToSecond.GetEnumerator();
        }

        public IEnumerator GetSecondEnumerator()
        {
            return secondToFirst.GetEnumerator();
        }
    }
}

1

විශාල නූල් කට්ටල සඳහා, ලැයිස්තුගත උදාහරණ වෙහෙසකර විය හැකිය. ඔබට තත්ව කේත ලැයිස්තුවක් හෝ වෙනත් නූල් මත පදනම් වූ එනූම් ලැයිස්තුවක් අවශ්‍ය නම්, ආරෝපණ පද්ධතියක් භාවිතා කිරීම කරදරයක් වන අතර, ස්ථිතික පංතියක්ම නිදසුන් සහිතව වින්‍යාස කිරීමට කරදරකාරී වේ. මගේම විසඳුම සඳහා, මම T4 සැකිලි භාවිතා කරමින් නූල්-පිටුබලය සහිත එනූම් ලබා ගැනීම පහසු කරමි. ප්‍රති H ලය එන්නේ HttpMethod පන්තිය ක්‍රියා කරන ආකාරය හා සමානය.

ඔබට එය මේ ආකාරයෙන් භාවිතා කළ හැකිය:

    string statusCode = ResponseStatusCode.SUCCESS; // Automatically converts to string when needed
    ResponseStatusCode codeByValueOf = ResponseStatusCode.ValueOf(statusCode); // Returns null if not found

    // Implements TypeConverter so you can use it with string conversion methods.
    var converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(ResponseStatusCode));
    ResponseStatusCode code = (ResponseStatusCode) converter.ConvertFromInvariantString(statusCode);

    // You can get a full list of the values
    bool canIterateOverValues = ResponseStatusCode.Values.Any(); 

    // Comparisons are by value of the "Name" property. Not by memory pointer location.
    bool implementsByValueEqualsEqualsOperator = "SUCCESS" == ResponseStatusCode.SUCCESS; 

ඔබ ආරම්භ කරන්නේ Enum.tt ගොනුවකින්.

<#@ include file="StringEnum.ttinclude" #>


<#+
public static class Configuration
{
    public static readonly string Namespace = "YourName.Space";
    public static readonly string EnumName = "ResponseStatusCode";
    public static readonly bool IncludeComments = true;

    public static readonly object Nodes = new
    {
        SUCCESS = "The response was successful.",
        NON_SUCCESS = "The request was not successful.",
        RESOURCE_IS_DISCONTINUED = "The resource requested has been discontinued and can no longer be accessed."
    };
}
#>

ඉන්පසු, ඔබ ඔබේ StringEnum.ttinclude ගොනුවට එක් කරන්න.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#@ CleanupBehavior processor="T4VSHost" CleanupAfterProcessingtemplate="true" #>

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;

namespace <#= Configuration.Namespace #>
{
    /// <summary>
    /// TypeConverter implementations allow you to use features like string.ToNullable(T).
    /// </summary>
    public class <#= Configuration.EnumName #>TypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            var casted = value as string;

            if (casted != null)
            {
                var result = <#= Configuration.EnumName #>.ValueOf(casted);
                if (result != null)
                {
                    return result;
                }
            }

            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var casted = value as <#= Configuration.EnumName #>;
            if (casted != null && destinationType == typeof(string))
            {
                return casted.ToString();
            }

            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

    [TypeConverter(typeof(<#= Configuration.EnumName #>TypeConverter))]
    public class <#= Configuration.EnumName #> : IEquatable<<#= Configuration.EnumName #>>
    {
//---------------------------------------------------------------------------------------------------
// V A L U E S _ L I S T
//---------------------------------------------------------------------------------------------------
<# Write(Helpers.PrintEnumProperties(Configuration.Nodes)); #>

        private static List<<#= Configuration.EnumName #>> _list { get; set; } = null;
        public static List<<#= Configuration.EnumName #>> ToList()
        {
            if (_list == null)
            {
                _list = typeof(<#= Configuration.EnumName #>).GetFields().Where(x => x.IsStatic && x.IsPublic && x.FieldType == typeof(<#= Configuration.EnumName #>))
                    .Select(x => x.GetValue(null)).OfType<<#= Configuration.EnumName #>>().ToList();
            }

            return _list;
        }

        public static List<<#= Configuration.EnumName #>> Values()
        {
            return ToList();
        }

        /// <summary>
        /// Returns the enum value based on the matching Name of the enum. Case-insensitive search.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static <#= Configuration.EnumName #> ValueOf(string key)
        {
            return ToList().FirstOrDefault(x => string.Compare(x.Name, key, true) == 0);
        }


//---------------------------------------------------------------------------------------------------
// I N S T A N C E _ D E F I N I T I O N
//---------------------------------------------------------------------------------------------------      
        public string Name { get; private set; }
        public string Description { get; private set; }
        public override string ToString() { return this.Name; }

        /// <summary>
        /// Implcitly converts to string.
        /// </summary>
        /// <param name="d"></param>
        public static implicit operator string(<#= Configuration.EnumName #> d)
        {
            return d.ToString();
        }

        /// <summary>
        /// Compares based on the == method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator !=(<#= Configuration.EnumName #> a, <#= Configuration.EnumName #> b)
        {
            return !(a == b);
        }

        /// <summary>
        /// Compares based on the .Equals method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator ==(<#= Configuration.EnumName #> a, <#= Configuration.EnumName #> b)
        {
            return a?.ToString() == b?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool Equals(object o)
        {
            return this.ToString() == o?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public bool Equals(<#= Configuration.EnumName #> other)
        {
            return this.ToString() == other?.ToString();
        }

        /// <summary>
        /// Compares based on the .Name property
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
    }
}

<#+

public static class Helpers
{
        public static string PrintEnumProperties(object nodes)
        {
            string o = "";
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props = nodesTp.GetProperties().OrderBy(p => p.Name).ToArray();

            for(int i = 0; i < props.Length; i++)
            {
                var prop = props[i];
                if (Configuration.IncludeComments)
                {
                    o += "\r\n\r\n";
                    o += "\r\n        ///<summary>";
                    o += "\r\n        /// "+Helpers.PrintPropertyValue(prop, Configuration.Nodes);
                    o += "\r\n        ///</summary>";
                }

                o += "\r\n        public static readonly "+Configuration.EnumName+" "+prop.Name+ " = new "+Configuration.EnumName+"(){ Name = \""+prop.Name+"\", Description = "+Helpers.PrintPropertyValue(prop, Configuration.Nodes)+ "};";
            }

            o += "\r\n\r\n";

            return o;
        }

        private static Dictionary<string, string> GetValuesMap()
        {
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props= nodesTp.GetProperties();
            var dic = new Dictionary<string,string>();
            for(int i = 0; i < props.Length; i++)
            {
                var prop = nodesTp.GetProperties()[i];
                dic[prop.Name] = prop.GetValue(Configuration.Nodes).ToString();
            }
            return dic;
        }

        public static string PrintMasterValuesMap(object nodes)
        {
            Type nodesTp = Configuration.Nodes.GetType();
            PropertyInfo[] props= nodesTp.GetProperties();
            string o = "        private static readonly Dictionary<string, string> ValuesMap = new Dictionary<string, string>()\r\n        {";
            for(int i = 0; i < props.Length; i++)
            {
                var prop = nodesTp.GetProperties()[i];
                o += "\r\n            { \""+prop.Name+"\", "+(Helpers.PrintPropertyValue(prop,Configuration.Nodes)+" },");
            }
            o += ("\r\n        };\r\n");

            return o;
        }


        public static string PrintPropertyValue(PropertyInfo prop, object objInstance)
        {
            switch(prop.PropertyType.ToString()){
                case "System.Double":
                    return prop.GetValue(objInstance).ToString()+"D";
                case "System.Float":
                    return prop.GetValue(objInstance).ToString()+"F";
                case "System.Decimal":
                    return prop.GetValue(objInstance).ToString()+"M";
                case "System.Long":
                    return prop.GetValue(objInstance).ToString()+"L";
                case "System.Boolean":
                case "System.Int16":
                case "System.Int32":
                    return prop.GetValue(objInstance).ToString().ToLowerInvariant();
                case "System.String":
                    return "\""+prop.GetValue(objInstance)+"\"";
            }

            return prop.GetValue(objInstance).ToString();
        }

        public static string _ (int numSpaces)
        {
            string o = "";
            for(int i = 0; i < numSpaces; i++){
                o += " ";
            }

            return o;
        }
}
#>

අවසාන වශයෙන්, ඔබ ඔබේ Enum.tt ගොනුව නැවත සකස් කරන අතර ප්‍රතිදානය මේ ආකාරයට පෙනේ:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System;
using System.Linq;
using System.Collections.Generic;

namespace YourName.Space
{
    public class ResponseStatusCode
    {
//---------------------------------------------------------------------------------------------------
// V A L U E S _ L I S T 
//---------------------------------------------------------------------------------------------------



        ///<summary>
        /// "The response was successful."
        ///</summary>
        public static readonly ResponseStatusCode SUCCESS = new ResponseStatusCode(){ Name = "SUCCESS", Description = "The response was successful."};


        ///<summary>
        /// "The request was not successful."
        ///</summary>
        public static readonly ResponseStatusCode NON_SUCCESS = new ResponseStatusCode(){ Name = "NON_SUCCESS", Description = "The request was not successful."};


        ///<summary>
        /// "The resource requested has been discontinued and can no longer be accessed."
        ///</summary>
        public static readonly ResponseStatusCode RESOURCE_IS_DISCONTINUED = new ResponseStatusCode(){ Name = "RESOURCE_IS_DISCONTINUED", Description = "The resource requested has been discontinued and can no longer be accessed."};


        private static List<ResponseStatusCode> _list { get; set; } = null;
        public static List<ResponseStatusCode> ToList()
        {
            if (_list == null)
            {
                _list = typeof(ResponseStatusCode).GetFields().Where(x => x.IsStatic && x.IsPublic && x.FieldType == typeof(ResponseStatusCode))
                    .Select(x => x.GetValue(null)).OfType<ResponseStatusCode>().ToList();
            }

            return _list;
        }

        public static List<ResponseStatusCode> Values()
        {
            return ToList();
        }

        /// <summary>
        /// Returns the enum value based on the matching Name of the enum. Case-insensitive search.
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static ResponseStatusCode ValueOf(string key)
        {
            return ToList().FirstOrDefault(x => string.Compare(x.Name, key, true) == 0);
        }


//---------------------------------------------------------------------------------------------------
// I N S T A N C E _ D E F I N I T I O N 
//---------------------------------------------------------------------------------------------------       
        public string Name { get; set; }
        public string Description { get; set; }
        public override string ToString() { return this.Name; }

        /// <summary>
        /// Implcitly converts to string.
        /// </summary>
        /// <param name="d"></param>
        public static implicit operator string(ResponseStatusCode d)
        {
            return d.ToString();
        }

        /// <summary>
        /// Compares based on the == method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator !=(ResponseStatusCode a, ResponseStatusCode b)
        {
            return !(a == b);
        }

        /// <summary>
        /// Compares based on the .Equals method. Handles nulls gracefully.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static bool operator ==(ResponseStatusCode a, ResponseStatusCode b)
        {
            return a?.ToString() == b?.ToString();
        }

        /// <summary>
        /// Compares based on the .ToString() method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public override bool Equals(object o)
        {
            return this.ToString() == o?.ToString();
        }

        /// <summary>
        /// Compares based on the .Name property
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.