我知道这听起来像是一个古老的愚蠢问题,但我在互联网上搜索过,我仍然不明白一件事。我知道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!
编辑:我更改了创建行,所以你们中的一些人想要为它打击我;)
答案 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