使用整数&设置枚举属性。验证参数

时间:2012-02-07 19:52:05

标签: c#

编辑:我已经更改了问题的标题,包括对参数的验证,以便更清楚我要问的内容。

我试图在C#中创建一个类,该类具有一个用int设置的属性并返回一个枚举,这可能是非常基本的,但我是一个C#noob。

使用int参数进行的设置是一个特殊的限制,我不会进入,并且是在Vbscript中设置COM的东西。

我希望创建这些RSSCalendarDay对象,这样它们就可以放在一个列表中,每个对象都有一个独特的RSSCalendarRuleDay,从周日到周六(1到7)。

它是将xCal与本地数据结合使用以制作重复事件的真正基本方法的一部分。

到目前为止我的代码在下面,您可以看到获取& set是不完整的,我坚持参数的验证(首先检查它是一个int,等等),这就是我之前尝试使用dayOrderValue的东西,而我在网上找到的所有东西都是使用int.Parse和int.TryParse但它们用于解析字符串,而不是我想要做的事情。

public class RSSCalendarDay {

    private RSSCalendarRuleDay? _dayOrder;
    /// <summary>
    /// Passed an Integer from 1 to 7 to represent the particular day of the week as an enum
    /// </summary>
    public RSSCalendarRuleDay? DayOrder {
        get {
                       // TODO
        } 
        set {
            if (value != null) {
                int dayOrderValue;
                if () {
                    throw new ArgumentException("Invalid day order specified");
                }
                if(dayOrderValue < 1 || dayOrderValue > 7) {
                    throw new ArgumentException("Invalid day type specified (out of day range of 1 to 7)");
                }
                _dayOrder = (RSSCalendarRuleDay) dayOrderValue;
            }
            else {
                _dayOrder = null;
            }
        } 
    }
    public DateTime? TimeOpens { get; set; }
    public DateTime? TimeCloses { get; set; }

    /// <summary>
    /// These are the relevant BYDAY abbreviations used in the xCal recurring rule specification
    /// to represent what days a recurring event is open in a comma separated list
    /// </summary>
    public enum RSSCalendarRuleDay {
        SU=1,MO=2,TU=3,WE=4,TH=5,FR=6,SA=7
    }
}

6 个答案:

答案 0 :(得分:3)

您可以将int转换为枚举,如此

RSSCalendarRuleDay foo = Enum.ToObject(typeof(RSSCalendarRuleDay) , intValue);

或者只是简单地施展它

RSSCalendarRuleDay foo = (RSSCalendarRuleDay) intValue;

请注意,由于您使用的是setter,因此setter会指望Enum值,而不是整数,因此您需要使用setter将强制转换为

请注意,即使未为Enum定义值,ToObject也将始终成功。如果要进行边界检查,可以使用Enum.IsDefined方法

var exists = Enum.IsDefined(typeof(RSSCalendarRuleDay) , intValue);

答案 1 :(得分:3)

您无法定义“使用int设置并返回枚举”的属性。根据设计,属性的getter和setter声明为相同类型。

但是,您可以做的是定义两个属性,它们都访问相同的支持字段,一个作为枚举,另一个转换为int:

public class RSSCalendarDay
{
    private RSSCalendarRuleDay? dayOrder;

    public RSSCalendarRuleDay? DayOrder
    {
        get { return this.dayOrder; }
        set { this.dayOrder = value; }
    }

    public int DayOrderInt
    {
        get { return this.dayOrder.HasValue ? (int)this.dayOrder: 0; }
        set { this.dayOrder = value != 0 ? (RSSCalendarRuleDay?)value : null; }
    }
}

在上面的代码中,如果指定int值为0(反之亦然),我已经简化了逻辑,将支持字段设置为null;这可能不是你想要的。

因此,以下两个作业将具有相同的效果:

RSSCalendarDay cd1 = new RSSCalendarDay();
cd1.DayOrder = RSSCalendarRuleDay.TH;

RSSCalendarDay cd2 = new RSSCalendarDay();
cd2.DayOrderInt = 5;

编辑:如果要执行参数验证,可以使用类似的方法:

public class RSSCalendarDay
{
    private RSSCalendarRuleDay dayOrder;

    public RSSCalendarRuleDay DayOrder
    {
        get { return this.dayOrder; }
        set { this.dayOrder = value; }
    }

    public int DayOrderInt
    {
        get 
        { 
            return (int)this.dayOrder;
        }
        set
        {
            if (!Enum.IsDefined(typeof(RSSCalendarRuleDay), value))
                throw new ArgumentException("Invalid day value specified (out of day range of 1 to 7).");
            this.dayOrder = (RSSCalendarRuleDay)value; 
        }
    }
}

Enum.IsDefined检查枚举是否包含指定的值。在您的情况下,条件等同于value < 1 || value > 7

请注意,在上面的代码中,DayOrder不可为空,0被视为无效的日期值。

编辑 2 :重新发出默认值问题:我个人的偏好是将枚举的0 th 成员定义为未知;继续你的双字母约定,我将其命名为NA(“不可用”)。

public enum RSSCalendarRuleDay {
    NA=0,SU=1,MO=2,TU=3,WE=4,TH=5,FR=6,SA=7
}

这很方便,因为当您初始化RSSCalendarDay实例而未明确设置其dayOrder字段时,它会自动默认为RSSCalendarRuleDay.NA。我上面给出的第二个片段也会随着这种改变而改变,因为Enum.IsDefined现在可以接受0-7(而不是1-7)的范围。

答案 2 :(得分:1)

不要使代码过于复杂:枚举在内部由数字表示(默认情况下为int),因此可以从int转换为enum值(反之亦然。)

所以这就是你可以做到的:

public RSSCalendarRuleDay DayOrder { get; set; }

...

RSSCalendarDay xx = new RSSCalendarDay(...)
xx.DayOrder = (DayOrder)4;  // Will set WE for the DayOrder property

...

// If you need to get the value as an int
int dayOrderAsInt = (int)xx.DayOrder;

// Still possible to affect invalid values however
RSSCalendarRuleDay z = (RSSCalendarRuleDay)8;

// So if you want to check for int validity:
if (Enum.IsDefined(typeof(RSSCalendarRuleDay), dayOrderAsInt))
{
    // If we're here, the value is valid !
}

另外,请确保您确实需要DayOrder可以为空(如果不是这样,请删除?)。

答案 3 :(得分:1)

问题是,由于您将属性设置为Enum,因此您无法在属性的setter中收到与Enum不同的内容。一种替代方案可能是这样的:

private int? dayOrderInt;

public int? DayOrderInt
{
     get { return dayOrderInt; }
     set { if (value < 1 || value > 7) throw new ArgumentException(string.Format("{0} is an invalid day of the week", value)); dayOrderInt = value; }
}

public RSSCalendarRuleDay? DayOrder
{
    get { if (DayOrderInt.HasValue) return (RSSCalendarRuleDay)DayOrderInt; return null; }
}

答案 4 :(得分:0)

以下对我有用:

RSSCalendarRuleDay Example = (RSSCalendarRuleDay)1; 

答案 5 :(得分:0)

我不认为这是可以实现的。您将属性类型设置为RSSCalendarRuleDay?当你想将az整数传递给它时,编译器将抛出一个错误。顺便说一句,这种方法非常容易混淆(比如当你打算返回一个IEnumerable但有时你会返回null)。