尝试有什么意义......除了......终于在德尔福?

时间:2016-06-19 11:19:36

标签: delphi

我知道这听起来像是一个古老的愚蠢问题,但我在互联网上搜索过,我仍然不明白一件事。我知道try-finally将在停止错误之前运行finally代码(或者在没有引发异常时不停止)并且try-except将在引发异常时运行except代码。但是我仍然不明白的是尝试 - 除了try-finally语句之外。我会写一个例子

我总是这样做:

using System;
using System.Collections.Generic;
using System.Linq;

namespace StackOverflowAnswer
{
    class Program
    {
        static string[] songs = new string[] { "song1", "song2", "song3" };
        static string[] days = new string[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };

        static void Main(string[] args)
        {
            var rnd = new Random();
            var allCombinationsInRandomOrder = GetCombinations(songs, songs.Length)
                .Select(combination => new { Combination = combination, Order = rnd.Next() })
                .OrderBy(entry => entry.Order)
                .Select(entry => entry.Combination);

            var dayIndex = 0;
            foreach (var combination in allCombinationsInRandomOrder)
            {
                var day = days[dayIndex];
                Console.WriteLine(day);
                Console.WriteLine(string.Join(", ", combination));

                dayIndex++;
                if (dayIndex >= days.Length)
                    break;
            }
            Console.ReadLine();
        }

        private static IEnumerable<IEnumerable<string>> GetCombinations(IEnumerable<string> songs, int numberOfSongsInGeneratedLists)
        {
            if (songs == null)
                throw new ArgumentNullException(nameof(songs));
            if (numberOfSongsInGeneratedLists <= 0)
                throw new ArgumentOutOfRangeException(nameof(numberOfSongsInGeneratedLists));
            if (numberOfSongsInGeneratedLists > songs.Count())
                throw new ArgumentOutOfRangeException("can't ask for more songs in the returned combinations that are provided", nameof(numberOfSongsInGeneratedLists));

            if (numberOfSongsInGeneratedLists == 1)
            {
                foreach (var song in songs)
                    yield return new[] { song };
                yield break;
            }

            foreach (var combinationWithOneSongTooFew in GetCombinations(songs, numberOfSongsInGeneratedLists - 1))
            {
                foreach (var song in songs.Where(song => !combinationWithOneSongTooFew.Contains(song)))
                    yield return combinationWithOneSongTooFew.Concat(new[] { song });
            }
        }
    }
}

我多年来从未使用过finally子句,因为我总是处理错误,而且我从未理解将它们嵌套在一起使用它们有什么意义。我的解决方案有什么不好的?为什么在示例中使用类似的东西很常见:

a:=x.Create;
try 
  a.DoRiskyStuff;
except
  ShowMessage('Error!');
end;
a.free;

有什么区别?当try-except?

之后可以完成所有清理时,为什么有人会使用finally子句?

非常感谢任何asnwers!

编辑:我更改了创建行,所以你们中的一些人想要为它打击我;)

1 个答案:

答案 0 :(得分:4)

这两种结构之间存在两个很大的差异。技术性和语义性。

技术

从技术上讲,区别在于即使没有异常,也会始终执行finally块,而except块仅在出现异常时执行。

使用finally块中的Exit提前退出函数时,甚至会执行try-finally块。

此外,finally块执行吞下异常,而except块通常吞下它,并且只有异常类型执行时它才能转义块与您在on ... do中指定的例外类型不匹配,或者您手动重新raise它。

语义

except块意味着处理异常,而finally块则不是。finally块。 X := TY.Create; try // Code that may raise an exception. finally X.Free; // Free resource, even if there was an exception. // Exception is NOT handled. end; 块意味着包含应该执行的代码而不管异常,即主要用于保护资源。这就是你应该做的原因:

try
  // Code that may raise an exception.
except
  // Handle the kind of exceptions you can handle.
end;

finally

请注意,使用Free的资源保护不仅限于内存和Cursor := crMultiDrag; try // Code that may raise exception. finally Cursor := crDefault; end; 。您可以恢复/撤消/关闭任何应该恢复/撤消/关闭的内容,即关闭打开的文件,关闭打开的连接,关闭已启动的硬件,将鼠标指针恢复到以前的格式等等。等等。

因此您也可以将其用于以下代码:

library(stringr)
SI <- c("HYUNDAI CRETA", "HYUNDAI VERNA")
SI <- str_c(SI, collapse = ",")

a <- paste0("select * from autotable where SUBBRAND like (",SI,")") 
a