Проверка, содержит ли параметр объекта datetime

#c# #.net

#c# #.net

Вопрос:

У меня есть метод с параметром объекта, чтобы он мог использоваться по-разному разными вызывающими методами. Внутри метода мне нужно проверить, является ли первым параметром объекта date или нет, если не установлена сегодняшняя дата.

 public void CreateNew(FileModel data, Object otherParams = null)
{
     DateTime portDate = DateTime.Now;
     if (otherParams is DateTime)
         portDate = (DateTime)otherParams;

    //In case 1 portDate is portDate value and in case 2 portDate value id 
    //DateTime.Now() even though portDate contains a value.
}
  

Я передаю объект этому методу в форме двумя способами, как показано ниже.

 CreateNew(fileData,new {portDate=portDate});
CreateNew(fileData,new {portDate=portDate,countries=countries});
  

Приведенный выше код работает в первом случае, но не работает во втором случае, и дата порта всегда является сегодняшней датой. Итак, как я могу использовать общий случай проверки даты для правильной обработки обоих случаев?

Комментарии:

1. Я чувствую, что вы злоупотребляете анонимными типами C #. Почему бы вместо этого не использовать строго типизированный параметр кортежа?

2. Моя рекомендация — не писать методы, которые будут использоваться иначе, чем другие вызывающие методы. Если otherParams могут быть разные вещи, как кто-нибудь узнает, что это может быть? Если вы опубликуете пример того, что некоторые из различных вариантов https://softwareengineering.stackexchange.com / тогда могут быть некоторые предложения о том, какие части можно использовать повторно и комбинировать, а какие хранить полностью отдельно. Потому что объединение для уменьшения дублирования — это хорошо, просто не так, чтобы намерения были неясными.

3. @Dai Мое понимание может быть совершенно неправильным, но могу ли я использовать tuple, когда я не всегда уверен в количестве параметров? Потому что в случае 1 есть 1, в случае 2 есть 2, и у меня может быть случай, когда их 3.

4. Вы не можете использовать tuple для этого, но почему бы не создать обычный класс?

5. Это должно быть формализовано как разные сигнатуры методов.

Ответ №1:

Вы можете использовать dynamic вместо Object , а затем проверить

 if (otherParams?.portDate is DateTime)
{ ...}
  

Хотя я согласен с комментарием, что вы, похоже, неправильно используете анонимные классы. Если вы знаете, что получаете, просто создайте реальный класс, который будет иметь DateTime portDate , чтобы вы знали наверняка.

Ответ №2:

вы можете просмотреть все свойства объекта и проверить, является ли одно из них datetime

     object example  = new {si= DateTime.Now, no= "no"}; //object example

    var typevar  = example.GetType().GetProperties(); //get all te props
    //lets loop all the props
    foreach(var i in typevar){
       if(i.PropertyType == typeof(System.DateTime)){
         //if is DateTime well write the name of prop with i.Name 
         Console.WriteLine("The propiertie {0} is date time", i.Name);
       }
    }
  

это также работает для динамических параметров

Ответ №3:

Ваш вопрос указывает на то, что if otherParams не является a DateTime , который вы будете использовать DateTime.Now . Это говорит о том, что если otherParams не a DateTime , то он не используется.

Если это так, то лучшей подписью может быть:

 public void CreateNew(FileModel data, DateTime? portDate = null)
  

Это дает понять вызывающему, который portDate должен быть a DateTime , но это необязательно. Затем вы можете сделать это:

 portDate = portDate ?? DateTime.Now;
  

Так что, если он не имеет значения, он заменяется на DateTime.Now .

Если существуют разные способы его вызова, вы можете обеспечить разные перегрузки в зависимости от того, как он должен быть вызван.

Вы также можете добавить:

 public void CreateNew(FileModel data, Countries countries, DateTime? portDate = null)
  

Если возможно, что любой из них может быть нулевым, но оба они не должны быть нулевыми, вы можете создать подписи, отражающие это, а затем заставить каждого из них вызвать private метод, который обрабатывает нули. Таким образом, вы более четко передаете ожидания.

Если что-то еще должно вызвать аналогичный метод, но второй параметр может быть чем-то совершенно другим (не датой), тогда лучше создать другой метод. Если тип параметра равен object , и одна из возможностей заключается в том, что это может быть a DateTime , и существует хотя бы один другой правильный тип, тогда вызывающий объект не сможет узнать, что он должен передать. Например, они могут вызывать:

 CreateNew(someFileModel, new List<string>());
  

… и он будет скомпилирован, но ваш метод не будет иметь для этого никакого смысла List<string> и может даже выдать исключение. Безопасность типов очень ценна, потому что она позволяет нам получить все это правильно заранее. Код даже не будет компилироваться, если мы не передаем правильный тип. Мы не хотим, чтобы наш код компилировался, а затем выдавал ошибку во время выполнения, если мы можем ее избежать.

В качестве общего руководства мы должны использовать только object в том случае, если тип действительно не имеет никакого значения. Вы можете передавать объекты String.Format , потому что в большинстве случаев это просто вызов ToString() , поэтому тип не имеет значения. в 90% или более случаев (я бы сказал, ближе к 99,5%) тип имеет значение. Если мы попадаем в тупик и чувствуем, что нам нужно использовать dynamic or object , тогда мы должны отступить и попытаться раскрасить себя из этого угла.