Операторы C# Nested Try Catch или методы?

Для быстрого и легкого использования я написал эту функцию некоторое время назад. Он возвращает разницу между двумя датами в хорошем формате. Не стесняйтесь использовать его (проверено на webkit).

/**
 * Function to print date diffs.
 * 
 * @param {Date} fromDate: The valid start date
 * @param {Date} toDate: The end date. Can be null (if so the function uses "now").
 * @param {Number} levels: The number of details you want to get out (1="in 2 Months",2="in 2 Months, 20 Days",...)
 * @param {Boolean} prefix: adds "in" or "ago" to the return string
 * @return {String} Diffrence between the two dates.
 */
function getNiceTime(fromDate, toDate, levels, prefix){
    var lang = {
            "date.past": "{0} ago",
            "date.future": "in {0}",
            "date.now": "now",
            "date.year": "{0} year",
            "date.years": "{0} years",
            "date.years.prefixed": "{0} years",
            "date.month": "{0} month",
            "date.months": "{0} months",
            "date.months.prefixed": "{0} months",
            "date.day": "{0} day",
            "date.days": "{0} days",
            "date.days.prefixed": "{0} days",
            "date.hour": "{0} hour",
            "date.hours": "{0} hours",
            "date.hours.prefixed": "{0} hours",
            "date.minute": "{0} minute",
            "date.minutes": "{0} minutes",
            "date.minutes.prefixed": "{0} minutes",
            "date.second": "{0} second",
            "date.seconds": "{0} seconds",
            "date.seconds.prefixed": "{0} seconds",
        },
        langFn = function(id,params){
            var returnValue = lang[id] || "";
            if(params){
                for(var i=0;i<params.length;i++){
                    returnValue = returnValue.replace("{"+i+"}",params[i]);
                }
            }
            return returnValue;
        },
        toDate = toDate ? toDate : new Date(),
        diff = fromDate - toDate,
        past = diff < 0 ? true : false,
        diff = diff < 0 ? diff * -1 : diff,
        date = new Date(new Date(1970,0,1,0).getTime()+diff),
        returnString = '',
        count = 0,
        years = (date.getFullYear() - 1970);
    if(years > 0){
        var langSingle = "date.year" + (prefix ? "" : ""),
            langMultiple = "date.years" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (years > 1 ? langFn(langMultiple,[years]) : langFn(langSingle,[years]));
        count ++;
    }
    var months = date.getMonth();
    if(count < levels && months > 0){
        var langSingle = "date.month" + (prefix ? "" : ""),
            langMultiple = "date.months" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (months > 1 ? langFn(langMultiple,[months]) : langFn(langSingle,[months]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var days = date.getDate() - 1;
    if(count < levels && days > 0){
        var langSingle = "date.day" + (prefix ? "" : ""),
            langMultiple = "date.days" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (days > 1 ? langFn(langMultiple,[days]) : langFn(langSingle,[days]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var hours = date.getHours();
    if(count < levels && hours > 0){
        var langSingle = "date.hour" + (prefix ? "" : ""),
            langMultiple = "date.hours" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (hours > 1 ? langFn(langMultiple,[hours]) : langFn(langSingle,[hours]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var minutes = date.getMinutes();
    if(count < levels && minutes > 0){
        var langSingle = "date.minute" + (prefix ? "" : ""),
            langMultiple = "date.minutes" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (minutes > 1 ? langFn(langMultiple,[minutes]) : langFn(langSingle,[minutes]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    var seconds = date.getSeconds();
    if(count < levels && seconds > 0){
        var langSingle = "date.second" + (prefix ? "" : ""),
            langMultiple = "date.seconds" + (prefix ? ".prefixed" : "");
        returnString += (count > 0 ?  ', ' : '') + (seconds > 1 ? langFn(langMultiple,[seconds]) : langFn(langSingle,[seconds]));
        count ++;
    } else {
        if(count > 0)
            count = 99;
    }
    if(prefix){
        if(returnString == ""){
            returnString = langFn("date.now");
        } else if(past)
            returnString = langFn("date.past",[returnString]);
        else
            returnString = langFn("date.future",[returnString]);
    }
    return returnString;
}
17
задан ghost 19 March 2009 в 19:37
поделиться

5 ответов

В контексте метода, который открывает файл, я использовал бы оператор использования по сравнению с выгодой попытки. Оператор использования гарантирует, чтобы Расположили, назван, если исключение происходит.

using (FileStream fs = new FileStream(file, FileMode.Open))
{
    //do stuff
}

делает то же самое как:

FileStream fs;
try
{
     fs = new FileStream(file, FileMode.Open);
     //do Stuff
 }
 finally
 {
        if(fs!=null)
           fs.Dispose();
 }
15
ответ дан 30 November 2019 в 11:32
поделиться

Теперь, когда у нас есть лямбды и вывод типа и некоторый другой материал, существует идиома, которая распространена в других языках, который теперь имеет много смысла в C#. Ваш пример был об открытии файла, выполнении чего-то к нему и затем закрытии его. Ну, теперь, можно сделать вспомогательный метод, который открывает файл и также заботится о проверке закрыться / располагают / моются, но обращается к лямбде, которую Вы предусматриваете, "действительно наполняют" часть. Это поможет, Вы получить сложную попытку/выгоду/наконец располагаете/очистка материал прямо в одном месте и затем используете его много раз.

Вот пример:

public static void ProcessFile(string filePath, Action<File> fileProcessor)
{
  File openFile = null;

  try
  {
    openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after.

    fileProcessor(openFile); 
  }
  finally
  {
    openFile.Close(); // Or dispose, or whatever.
  }
}

Теперь, вызывающие стороны этого метода не должны волноваться о том, как открыть файл, или близко / избавляются от него. Они могут сделать что-то вроде этого:

Helpers.ProcessFile("C://somefile.txt", f => 
 {
   while(var text = f.ReadLine())
   {
     Console.WriteLine(text);
   }
 });
11
ответ дан 30 November 2019 в 11:32
поделиться

Это - вопрос о стиле, но для меня я пытаюсь никогда не иметь больше чем один уровень вложения попытки/выгоды/наконец в отдельном методе. В точке Вы поражаете вложенную попытку, Вы почти наверняка нарушили 1 функцию = 1 операционный принципал и должны использовать второй метод.

7
ответ дан 30 November 2019 в 11:32
поделиться

Зависит от того, что Вы пытаетесь сделать, но в большинстве случаев, вложенная попытка/выгоды является знаком сверхкомплексной функции (или программиста, который не вполне знает, как работают исключения!).

В случае открытого файла, я использовал бы держателя IDisposable и пункт использования, и тем самым воздержался бы от потребности любой явной попытки/выгоды.

4
ответ дан 30 November 2019 в 11:32
поделиться

Большую часть времени я разбил бы вложенные блоки попытки/выгоды в функции. Но я иногда писал код, чтобы поймать и зарегистрировать все неперехваченные исключения, выданные моим приложением. Но что, если регистрирующийся код перестал работать? Таким образом, у меня есть еще одна попытка/выгода вокруг этого только, чтобы препятствовать тому, чтобы пользователь видел диалоговое окно необработанного исключения.NET по умолчанию. Но даже этот код мог очень легко быть пересмотрен в функции вместо вложенных блоков попытки/выгоды.

try
{
    try
    {
        DoEverything(); 
    }
    catch (Exception ex)
    {
        // Log the exception here
    }
}
catch (Exception ex)
{
    // Wow, even the log is broken ...
}
1
ответ дан 30 November 2019 в 11:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: