Saya mencoba untuk mendefinisikan Enum
dan menambahkan pemisah umum yang valid yang digunakan dalam CSV atau file serupa. Kemudian saya akan mengikatnya ke ComboBox
sebagai sumber data jadi setiap kali saya menambahkan atau menghapus dari definisi Enum, saya tidak perlu mengubah apa pun di kotak kombo.
Masalahnya adalah bagaimana saya bisa mendefinisikan enum dengan representasi string, seperti:
public enum SeparatorChars{Comma = ",", Tab = "\t", Space = " "}
Jawaban:
Anda tidak bisa - nilai enum harus berupa nilai integral. Anda dapat menggunakan atribut untuk mengaitkan nilai string dengan setiap nilai enum, atau dalam kasus ini jika setiap pemisah adalah satu karakter, Anda dapat menggunakan
char
nilainya:enum Separator { Comma = ',', Tab = '\t', Space = ' ' }
(EDIT: Hanya untuk memperjelas, Anda tidak dapat membuat
char
jenis enum yang mendasari, tetapi Anda dapat menggunakanchar
konstanta untuk menetapkan nilai integral yang sesuai dengan setiap nilai enum. Jenis yang mendasari enum di atas adalahint
.)Kemudian metode ekstensi jika Anda membutuhkannya:
public string ToSeparatorString(this Separator separator) { // TODO: validation return ((char) separator).ToString(); }
sumber
Sejauh yang saya tahu, Anda tidak akan diizinkan untuk menetapkan nilai string ke enum. Yang dapat Anda lakukan adalah membuat kelas dengan konstanta string di dalamnya.
public static class SeparatorChars { public static String Comma { get { return ",";} } public static String Tab { get { return "\t,";} } public static String Space { get { return " ";} } }
sumber
separator
sekarang berupa string (bisa apa saja), bukanSeparator
tipe dengan nilai valid terbatas.Anda dapat mencapainya tetapi akan membutuhkan sedikit kerja.
Lihat: Enum Dengan Nilai String Di C #
sumber
Untuk enum sederhana dari nilai string (atau tipe lainnya):
public static class MyEnumClass { public const string MyValue1 = "My value 1", MyValue2 = "My value 2"; }
Pemakaian:
string MyValue = MyEnumClass.MyValue1;
sumber
Anda tidak dapat melakukan ini dengan enum, tetapi Anda dapat melakukannya seperti itu:
public static class SeparatorChars { public static string Comma = ","; public static string Tab = "\t"; public static string Space = " "; }
sumber
comboBox.DataSource = Enum.GetValues(typeof(myEnum));
dalam kasus ini?switch-case
blok. Bidang harusconst
dalam rangka. Tapi itu tetap tidak bisa dihindari jika Anda mauEnum.GetValues(typeof(myEnum))
.const
sebagai gantinyastatic
. Konstanta bersifat hanya baca serta statis dan tidak dapat diasosiasikan dalam konstruktor (kecuali bidang hanya baca).Anda tidak bisa, karena enum hanya dapat didasarkan pada tipe numerik primitif. Anda dapat mencoba menggunakan
Dictionary
:Dictionary<String, char> separators = new Dictionary<string, char> { {"Comma", ','}, {"Tab", '\t'}, {"Space", ' '}, };
Alternatifnya, Anda bisa menggunakan a
Dictionary<Separator, char>
atauDictionary<Separator, string>
whereSeparator
adalah enum normal:enum Separator { Comma, Tab, Space }
yang akan sedikit lebih menyenangkan daripada menangani string secara langsung.
sumber
Kelas yang mengemulasi perilaku enum tetapi menggunakan
string
alih-alihint
dapat dibuat sebagai berikut ...public class GrainType { private string _typeKeyWord; private GrainType(string typeKeyWord) { _typeKeyWord = typeKeyWord; } public override string ToString() { return _typeKeyWord; } public static GrainType Wheat = new GrainType("GT_WHEAT"); public static GrainType Corn = new GrainType("GT_CORN"); public static GrainType Rice = new GrainType("GT_RICE"); public static GrainType Barley = new GrainType("GT_BARLEY"); }
Pemakaian...
kemudian...
public void PrintGrainKeyword(GrainType grain) { Console.Writeline("My Grain code is " + grain.ToString()); // Displays "My Grain code is GT_WHEAT" }
sumber
GrainType myGrain = "GT_CORN"
, misalnya.Ini agak terlambat untuk dijawab, tapi mungkin itu membantu seseorang di masa depan. Saya merasa lebih mudah menggunakan struct untuk masalah seperti ini.
Contoh berikut adalah bagian yang disalin dari kode MS:
namespace System.IdentityModel.Tokens.Jwt { // // Summary: // List of registered claims from different sources http://tools.ietf.org/html/rfc7519#section-4 // http://openid.net/specs/openid-connect-core-1_0.html#IDToken public struct JwtRegisteredClaimNames { // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Actort = "actort"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Typ = "typ"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Sub = "sub"; // // Summary: // http://openid.net/specs/openid-connect-frontchannel-1_0.html#OPLogout public const string Sid = "sid"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Prn = "prn"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Nbf = "nbf"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string Nonce = "nonce"; // // Summary: // http://tools.ietf.org/html/rfc7519#section-4 public const string NameId = "nameid"; } }
sumber
Mungkin sudah terlambat, tapi ini dia.
Kita dapat menggunakan atribut EnumMember untuk mengelola nilai Enum.
public enum EUnitOfMeasure { [EnumMember(Value = "KM")] Kilometer, [EnumMember(Value = "MI")] Miles }
Dengan cara ini nilai hasil untuk EUnitOfMeasure akan menjadi KM atau MI. Ini juga bisa dilihat dalam jawaban Andrew Whitaker .
sumber
Untuk orang yang tiba di sini mencari jawaban untuk pertanyaan yang lebih umum, Anda dapat memperluas konsep kelas statis jika ingin kode Anda terlihat seperti
enum
.Pendekatan berikut bekerja ketika Anda belum menyelesaikan yang
enum names
Anda inginkan danenum values
merupakanstring
representasi darienam name
; gunakannameof()
untuk membuat refactoring Anda lebih sederhana.public static class Colours { public static string Red => nameof(Red); public static string Green => nameof(Green); public static string Blue => nameof(Blue); }
Ini mencapai maksud dari enum yang memiliki nilai string (seperti pseudocode berikut):
public enum Colours { "Red", "Green", "Blue" }
sumber
Saya membuat kelas dasar untuk membuat enum bernilai string di .NET. Ini hanyalah satu file C # yang dapat Anda salin & tempel ke proyek Anda, atau instal melalui paket NuGet bernama StringEnum .
Pemakaian:
///<completionlist cref="HexColor"/> class HexColor : StringEnum<HexColor> { public static readonly HexColor Blue = New("#FF0000"); public static readonly HexColor Green = New("#00FF00"); public static readonly HexColor Red = New("#000FF"); }
fitur
// 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)
<completitionlist>
. (Bekerja di C # dan VB): misPemasangan
Antara:
.Net Standard 1.0
padanya sehingga berjalan di.Net Core
> = 1.0,.Net Framework
> = 4.5,Mono
> = 4.6, dll.public abstract class StringEnum<T> : IEquatable<T> where T : StringEnum<T>, new() { protected string Value; private static IList<T> valueList = new List<T>(); protected static T New(string value) { if (value == null) return null; // the null-valued instance is null. var result = new T() { Value = value }; valueList.Add(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 sensitivity.</param> public static T Parse(string value, bool caseSensitive = false) { 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 sensitivity.</param> public static T TryParse(string value, bool caseSensitive = false) { if (value == null) return null; if (valueList.Count == 0) System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typeof(T).TypeHandle); // force static fields initialization var field = valueList.FirstOrDefault(f => f.Value.Equals(value, caseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)); // Not using InvariantCulture because it's only supported in NETStandard >= 2.0 if (field == null) return null; return field; } }
Newtonsoft.Json
dukungan serialisasi, salin versi diperpanjang ini sebagai gantinya. StringEnum.csSaya menyadari setelah fakta bahwa kode ini mirip dengan jawaban Ben. Saya dengan tulus menulisnya dari awal. Namun saya pikir ini memiliki beberapa tambahan, seperti
<completitionlist>
retas, kelas yang dihasilkan terlihat lebih seperti Enum, tidak ada penggunaan refleksi pada Parse (), paket NuGet dan repo di mana saya mudah-mudahan akan membahas masalah yang masuk dan umpan balik.sumber
Membangun beberapa jawaban di sini saya telah menerapkan kelas dasar yang dapat digunakan kembali yang meniru perilaku enum tetapi dengan
string
sebagai tipe yang mendasarinya. Ini mendukung berbagai operasi termasuk:.Equals
,==
dan!=
Ini adalah kelas dasar secara keseluruhan:
public abstract class StringEnumBase<T> : IEquatable<T> where T : StringEnumBase<T> { public string Value { get; } protected StringEnumBase(string value) => this.Value = value; public override string ToString() => this.Value; public static List<T> AsList() { return typeof(T) .GetProperties(BindingFlags.Public | BindingFlags.Static) .Where(p => p.PropertyType == typeof(T)) .Select(p => (T)p.GetValue(null)) .ToList(); } public static T Parse(string value) { List<T> all = AsList(); if (!all.Any(a => a.Value == value)) throw new InvalidOperationException($"\"{value}\" is not a valid value for the type {typeof(T).Name}"); return all.Single(a => a.Value == value); } public bool Equals(T other) { if (other == null) return false; return this.Value == other?.Value; } public override bool Equals(object obj) { if (obj == null) return false; if (obj is T other) return this.Equals(other); return false; } public override int GetHashCode() => this.Value.GetHashCode(); public static bool operator ==(StringEnumBase<T> a, StringEnumBase<T> b) => a?.Equals(b) ?? false; public static bool operator !=(StringEnumBase<T> a, StringEnumBase<T> b) => !(a?.Equals(b) ?? false); public class JsonConverter<T> : Newtonsoft.Json.JsonConverter where T : StringEnumBase<T> { public override bool CanRead => true; public override bool CanWrite => true; public override bool CanConvert(Type objectType) => ImplementsGeneric(objectType, typeof(StringEnumBase<>)); private static bool ImplementsGeneric(Type type, Type generic) { while (type != null) { if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return true; type = type.BaseType; } return false; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JToken item = JToken.Load(reader); string value = item.Value<string>(); return StringEnumBase<T>.Parse(value); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { if (value is StringEnumBase<T> v) JToken.FromObject(v.Value).WriteTo(writer); } } }
Dan inilah cara Anda menerapkan "string enum":
[JsonConverter(typeof(JsonConverter<Colour>))] public class Colour : StringEnumBase<Colour> { private Colour(string value) : base(value) { } public static Colour Red => new Colour("red"); public static Colour Green => new Colour("green"); public static Colour Blue => new Colour("blue"); }
Yang bisa digunakan seperti ini:
public class Foo { public Colour colour { get; } public Foo(Colour colour) => this.colour = colour; public bool Bar() { if (this.colour == Colour.Red || this.colour == Colour.Blue) return true; else return false; } }
Saya harap seseorang menemukan ini berguna!
sumber
Pertama-tama Anda mencoba menetapkan string, bukan karakter, meskipun itu hanya satu karakter. gunakan ',' bukan ",". Hal berikutnya adalah, enum hanya mengambil tipe integral tanpa
char
Anda dapat menggunakan nilai unicode, tetapi saya akan sangat menyarankan Anda untuk tidak melakukannya. Jika Anda yakin bahwa nilai-nilai ini tetap sama, dalam budaya dan bahasa yang berbeda, saya akan menggunakan kelas statis dengan string const.sumber
Meskipun sangat tidak mungkin untuk menggunakan a
char
atau astring
sebagai basis untuk enum, saya rasa ini bukan yang benar-benar ingin Anda lakukan.Seperti yang Anda sebutkan, Anda ingin memiliki enum kemungkinan dan menunjukkan representasi string ini dalam kotak kombo. Jika pengguna memilih salah satu representasi string ini, Anda ingin mengeluarkan enum yang sesuai. Dan ini mungkin:
Pertama kita harus menghubungkan beberapa string ke nilai enum. Ini dapat dilakukan dengan menggunakan
DescriptionAttribute
seperti yang dijelaskan di sini atau di sini .Sekarang Anda perlu membuat daftar nilai enum dan deskripsi yang sesuai. Ini dapat dilakukan dengan menggunakan metode berikut:
/// <summary> /// Creates an List with all keys and values of a given Enum class /// </summary> /// <typeparam name="T">Must be derived from class Enum!</typeparam> /// <returns>A list of KeyValuePair<Enum, string> with all available /// names and values of the given Enum.</returns> public static IList<KeyValuePair<T, string>> ToList<T>() where T : struct { var type = typeof(T); if (!type.IsEnum) { throw new ArgumentException("T must be an enum"); } return (IList<KeyValuePair<T, string>>) Enum.GetValues(type) .OfType<T>() .Select(e => { var asEnum = (Enum)Convert.ChangeType(e, typeof(Enum)); return new KeyValuePair<T, string>(e, asEnum.Description()); }) .ToArray(); }
Sekarang Anda akan memiliki daftar pasangan nilai kunci dari semua enum dan deskripsinya. Jadi mari kita tetapkan ini sebagai sumber data untuk kotak kombo.
var comboBox = new ComboBox(); comboBox.ValueMember = "Key" comboBox.DisplayMember = "Value"; comboBox.DataSource = EnumUtilities.ToList<Separator>(); comboBox.SelectedIndexChanged += (sender, e) => { var selectedEnum = (Separator)comboBox.SelectedValue; MessageBox.Show(selectedEnum.ToString()); }
Pengguna melihat semua representasi string dari enum dan dalam kode Anda, Anda akan mendapatkan nilai enum yang diinginkan.
sumber
Kami tidak dapat mendefinisikan enumerasi sebagai tipe string. Jenis yang disetujui untuk enum adalah byte, sbyte, short, ushort, int, uint, long, atau ulong.
Jika Anda membutuhkan informasi lebih lanjut tentang pencacahan, silakan ikuti tautan di bawah ini, tautan itu akan membantu Anda memahami pencacahan. Pencacahan
@narendras
sumber
Ini bekerja untuk saya ..
public class ShapeTypes { private ShapeTypes() { } public static string OVAL { get { return "ov"; } private set { } } public static string SQUARE { get { return "sq"; } private set { } } public static string RECTANGLE { get { return "rec"; } private set { } } }
sumber
Apa yang baru-baru ini saya mulai lakukan adalah menggunakan Tuple
public static (string Fox, string Rabbit, string Horse) Animals = ("Fox", "Rabbit", "Horse"); ... public static (string Comma, string Tab, string Space) SeparatorChars = (",", "\t", " ");
sumber
public sealed class GenericDateTimeFormatType { public static readonly GenericDateTimeFormatType Format1 = new GenericDateTimeFormatType("dd-MM-YYYY"); public static readonly GenericDateTimeFormatType Format2 = new GenericDateTimeFormatType("dd-MMM-YYYY"); private GenericDateTimeFormatType(string Format) { _Value = Format; } public string _Value { get; private set; } }
public static void Main() { Country A = new Country(); A.DefaultDateFormat = GenericDateTimeFormatType.Format1; Console.ReadLine(); }
sumber