如何创建具有多个 属性 的 C# 枚举
How to create a c# enumeration with more than one property
我想创建一个类似对象的枚举,但有一个额外的 "property"。
例如我可以枚举星期几:
enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
现在,假设我还有一个 属性 我想每天存储。永远不会改变的东西。为了争论起见,假设我们有一个永远不变的工资率,周六为 1.5,周日为 2,其他时间为 1。
枚举无法做到这一点。我正在考虑创建一个 "helper" 静态 class,它只会 return 这一秒 属性,但这看起来很笨拙。
static class Rate
{
static float GetRate(Day d)
{
switch (d)
{
case Day.Saturday:
return 1.5f;
case Day.Sunday:
return 2f;
default:
return 1f;
}
}
}
我可以使用 ReadOnlyCollection 来代替带助手的枚举 class,但这对于我需要的东西来说似乎很复杂且重量级。
去这里最好的方法是什么?
可能是这样的:
public struct Day
{
public Day(int key, float rate)
{
_key = key;
_rate = rate;
}
private readonly int _key;
private readonly float _rate;
public int Key => _key;
public float Rate => _rate;
public static readonly Day
Monday = new Day(0, 1f),
Tuesday = new Day(0, 1f), ...;
public static implicit operator int(Day day) => day.Key;
}
然后 Day.Monday.Rate
起作用,int day = Day.Monday
起作用。
您可以像这样向枚举值添加自定义属性:
enum Day {
[MyAttr(Rate=1.5f)]
Sunday,
[MyAttr(Rate=2)]
Monday
}
public class MyAttr : Attribute {
public float Rate {get;set;}
}
然后像这样读取属性:
public float GetRate(Day day) {
MemberInfo memberInfo = typeof(Day).GetMember(day.ToString()).FirstOrDefault();
if (memberInfo != null) {
MyAttr attribute = (MyAttr)memberInfo
.GetCustomAttributes(typeof(MyAttr), false)
.FirstOrDefault();
return attribute.Rate;
}
return 0;
}
C# 枚举值是简单的单一值,这与其他语言不同,在其他语言中它们可以是复杂类型(例如元组)。
如果枚举值表示不可变数据的 "key",您可以通过使用带有 switch
块的扩展方法来破解它 - 类似于您的示例,但使用时语法更清晰:
enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
public static class DayExtensions
{
public static Single GetRate(this Day d)
{
switch( d )
{
case Day.Saturday:
return 1.5f;
case Day.Sunday:
return 2f;
default:
return 1f;
}
}
}
用法:
Day d = Day.Monday;
Single rate = d.GetRate();
您可以使用带有预定义静态实例的密封 class。额外的 属性(或属性)可以读作 属性,或通过隐式转换。
public sealed class Day
{
private Day(float rate)
{
m_Rate = rate;
}
private readonly float m_Rate;
public float Rate { get { return m_Rate; } }
public static readonly Day Saturday = new Day(1.5f);
public static readonly Day Sunday = new Day(2f);
public static readonly Day Monday = new Day(1f);
public static readonly Day Tuesday = new Day(1f);
public static readonly Day Wednesday = new Day(1f);
public static readonly Day Thursday = new Day(1f);
public static readonly Day Friday = new Day(1f);
public static implicit operator float(Day day)
{
return day.m_Rate;
}
}
用法:
var day = Day.Sunday;
var rate = day.Rate; // Use property
float rate2 = day; // Use implicit conversion
我想创建一个类似对象的枚举,但有一个额外的 "property"。
例如我可以枚举星期几:
enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
现在,假设我还有一个 属性 我想每天存储。永远不会改变的东西。为了争论起见,假设我们有一个永远不变的工资率,周六为 1.5,周日为 2,其他时间为 1。
枚举无法做到这一点。我正在考虑创建一个 "helper" 静态 class,它只会 return 这一秒 属性,但这看起来很笨拙。
static class Rate
{
static float GetRate(Day d)
{
switch (d)
{
case Day.Saturday:
return 1.5f;
case Day.Sunday:
return 2f;
default:
return 1f;
}
}
}
我可以使用 ReadOnlyCollection 来代替带助手的枚举 class,但这对于我需要的东西来说似乎很复杂且重量级。
去这里最好的方法是什么?
可能是这样的:
public struct Day
{
public Day(int key, float rate)
{
_key = key;
_rate = rate;
}
private readonly int _key;
private readonly float _rate;
public int Key => _key;
public float Rate => _rate;
public static readonly Day
Monday = new Day(0, 1f),
Tuesday = new Day(0, 1f), ...;
public static implicit operator int(Day day) => day.Key;
}
然后 Day.Monday.Rate
起作用,int day = Day.Monday
起作用。
您可以像这样向枚举值添加自定义属性:
enum Day {
[MyAttr(Rate=1.5f)]
Sunday,
[MyAttr(Rate=2)]
Monday
}
public class MyAttr : Attribute {
public float Rate {get;set;}
}
然后像这样读取属性:
public float GetRate(Day day) {
MemberInfo memberInfo = typeof(Day).GetMember(day.ToString()).FirstOrDefault();
if (memberInfo != null) {
MyAttr attribute = (MyAttr)memberInfo
.GetCustomAttributes(typeof(MyAttr), false)
.FirstOrDefault();
return attribute.Rate;
}
return 0;
}
C# 枚举值是简单的单一值,这与其他语言不同,在其他语言中它们可以是复杂类型(例如元组)。
如果枚举值表示不可变数据的 "key",您可以通过使用带有 switch
块的扩展方法来破解它 - 类似于您的示例,但使用时语法更清晰:
enum Day {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday };
public static class DayExtensions
{
public static Single GetRate(this Day d)
{
switch( d )
{
case Day.Saturday:
return 1.5f;
case Day.Sunday:
return 2f;
default:
return 1f;
}
}
}
用法:
Day d = Day.Monday;
Single rate = d.GetRate();
您可以使用带有预定义静态实例的密封 class。额外的 属性(或属性)可以读作 属性,或通过隐式转换。
public sealed class Day
{
private Day(float rate)
{
m_Rate = rate;
}
private readonly float m_Rate;
public float Rate { get { return m_Rate; } }
public static readonly Day Saturday = new Day(1.5f);
public static readonly Day Sunday = new Day(2f);
public static readonly Day Monday = new Day(1f);
public static readonly Day Tuesday = new Day(1f);
public static readonly Day Wednesday = new Day(1f);
public static readonly Day Thursday = new Day(1f);
public static readonly Day Friday = new Day(1f);
public static implicit operator float(Day day)
{
return day.m_Rate;
}
}
用法:
var day = Day.Sunday;
var rate = day.Rate; // Use property
float rate2 = day; // Use implicit conversion