1

我有一个类,它是数据库中的一个实体,它有一堆日期表示为字符串。例如,它可能是这样的:

public class Stuff
{
    public string Date1 {get;set;}
    public string Date2 {get;set;}
    public string Date3 {get;set;}
    public string Date4 {get;set;}
}

然后我有一个验证方法来验证其他属性并验证日期属性。目前,我正在为每个对象分别验证每个日期。这可行,但我想知道是否有一种方法可以使其通用,因此我不必在类之间和类本身内复制代码。我目前正在做类似的事情:

public bool ValidateDate(string date)
{
    string[] overrides = {"","__/__/____"};

    bool success = true;
    DateTime dateTime;

    if(!overrides.Contains(date) && !DateTime.TryParse(date,out dateTime))
    {
        success = false;
    }


    return success;
}

//Notice in this method I am repeating the if statements.
public bool Validate(Stuff stuff, out string message)
{
    message = string.Empty;
    bool success = true;

    if(!ValidateDate(stuff.Date1))
    {
        success = false;
        message = "Date 1 is invalid";
    }

    if(!ValidateDate(stuff.Date2))
    {
        success = false;
        message = "Date 2 is invalid";
    }

    if(!ValidateDate(stuff.Date3))
    {
        success = false;
        message = "Date 3 is invalid";
    }

    if(!ValidateDate(stuff.Date4))
    {
        success = false;
        message = "Date 4 is invalid";
    }

    return success;
}

void Main()
{
    string message;

    Stuff stuff = new Stuff();
    stuff.Date1 = "01/01/2020";
    stuff.Date2 = "__/__/____";
    stuff.Date3 = "";
    stuff.Date4 = "44/__/____";


    bool valid = Validate(stuff, out message);

}

我想过做类似的事情:

public bool Validate<T>(T value, out string message)
{
    //Validation here
}

但是,如果我错了,请纠正我,但这需要我获取属性并使用反射来检查日期的值,而我的另一个问题是属性是字符串,所以我无法检查如果是日期时间?

4

3 回答 3

1

我觉得我错过了一些信息——现在我看到的重复是你多次调用 ValidateDate。我认为没有办法解决这个问题 - 你必须在每个 Date 属性上调用 Validate ,除非(如你所提到的)你想走反射路线。

通过反射,您只需遍历所有属性并找到名称与模式匹配的任何属性,Date[number]然后您将验证它确实是一个DateTimeParse就像您已经做的那样),然后继续。

如果字段的数量是已知的并且不是太多,我会坚持使用您的ValidateMethod通知,该通知message目前只会向您显示最后一个错误(每次都会被覆盖)。

您可以变得可爱并编写如下方法:

public bool Validate(Stuff stuff, out string message)
{
    message = "Invalid Date(s): ";

    return ValidateDates(ref message, stuff.Date1, stuff.Date2, stuff.Date3, stuff.Date4);
}

public bool ValidateDate(ref string message, params string[] dates)
{
    bool rv = true;

    for (int i = 0; i < dates.Length; i++)
    {
        if (![validate DateTime as above])
        {
            message += i + " "; // add the failed index to the message
            rv = false;
        }
    }
    return rv;
}
于 2013-06-20T04:18:07.887 回答
0

您能做的最好的事情可能就是这样,尽管我不提倡使用字符串来表示日期。

public bool ValidateDates(params string[] dates)
{
    return dates.All( d => ValidateDate(d));
}

public bool Validate(Stuff stuff, out string message)
{

    ValidateDates(stuff.Date1,stuff.Date2,stuff.Date3);
}

你显然可以玩弄这个来知道哪个日期失败了,例如你可以做类似的事情

var item = dates.Select( d, i => new 
{
   Valid = ValidateDate(d),
   Message = String.Format("Date {0} failed", i)
}).FirstOrDefault( x => !x.Valid);

if(item == null) //everything is valid
  return true;
else 
   //set the out param
   outMessageStr = item.Message;

return false;
于 2013-06-20T04:13:51.707 回答
0

可以通过为要从中获取日期的对象使用接口来使所有内容都通用。

例如:

//Defines an interface that provides a function to get multiple dates from an object.
public interface IGetDates
{
     //You could use a Read-Only property too
     string[] GetDates();
}

public class Stuff : IGetDate
{
     //other stuff...

     public string[] GetDates()
     {
          return new[]{ Date1, Date2, Date2, ect...};
     }
}

然后您的通用方法将如下所示:

//Uses generic constraints so only objects that use the 
//IGetDates interface can call this method.
public bool Validate<T>(T stuff, out string message) where T : IGetDates
{
     message = string.Empty;
     bool success = true;
     string[] dates = stuff.GetDates();
     for(int i = 0; i < dates.Length; i++)
     {
          if(!Validate(dates[i]))
          {
              success = false;
              message = string.Format("Date {0} is invalid.", i);
          }
     }
     return success;
}
于 2013-06-20T04:30:35.880 回答