我知道在 C/C++ 等其他语言中,您会返回一个类似 SUCCESS 的值,这将指示调用方法该方法返回成功还是失败。
在 C# 中是否有一种“好”的方法可以在不需要 SUCCESS 返回变量的情况下执行此操作?想到抛出异常,但我不确定如何实现这一点。您是否可以使用自己的错误消息抛出自定义异常?
示例代码将不胜感激。
先感谢您。
我知道在 C/C++ 等其他语言中,您会返回一个类似 SUCCESS 的值,这将指示调用方法该方法返回成功还是失败。
在 C# 中是否有一种“好”的方法可以在不需要 SUCCESS 返回变量的情况下执行此操作?想到抛出异常,但我不确定如何实现这一点。您是否可以使用自己的错误消息抛出自定义异常?
示例代码将不胜感激。
先感谢您。
1)我不建议使用异常,除非失败是“异常的”。例如,它失败了,这意味着需要处理一些事情。它们比“假”类型的返回要慢。
2)你为什么要避免返回值?你必须没有返回值吗?
你指的是bool
数据类型吗?
函数定义示例:
public static bool DoSomething()
{
if ( some || condition )
return true;
else
return false;
}
使用示例:
public static void main()
{
if ( DoSomething() )
Console.WriteLine( "SUCCESS" );
else
Console.WriteLine( "FAILURE" );
}
如果您的方法是void
,那么它返回而不抛出异常的事实被认为是成功的。
如果您的方法不是 void,那么特定的返回值可能会被解释为不成功的执行,例如:
bool
方法返回false
null
不要将异常用于流量控制或表示“成功”。
如果除了返回参数之外,还希望有成功或失败的指示符,则可以out bool
在方法签名中使用参数。
public SomeObject DoingSomethingHere(out bool success)
{
}
if (!success)
{
// some compensating action
}
听起来您想指示一个方法在不使用返回值或异常的情况下没有成功完成。一个out bool
参数呢?
public void Execute(out bool success) {
try {
//...
success = true;
} catch {
success = false
}
}
我不建议这样做,但既然你问了......
不抛出异常将是我想到的方式......
基本上有四种方法可以从函数中获取消息:
如果出现意外问题,我会抛出异常。如果我期望某些东西不会一直起作用,我会使用返回值。
对于某些类型的故障,自定义异常当然是一个好方法。一种简单的方法是DomainException
在一个公共库中创建一个类(或任何您想为应用程序的问题域调用的类等),该类继承自Exception
并添加您认为对自定义域异常有用的任何特定信息. (可能是特定代码,可能是标准中可能没有的有关当前环境的信息Exception
等)
从那里,您可以创建更具体的异常,从那里继承,DataIntegrityException
例如,如果方法接收到在技术层面上有意义但违反自定义业务验证规则等的输入,则可以抛出异常。
您可以从 Exception 派生自己的异常。
您可以返回一个布尔值或一些数字约定。
在 C# 中,如果您想返回成功/失败,您可以使用比指针更容易使用的输出参数,以及产品输出。
对于特殊的事情,我倾向于例外。逻辑事物的逻辑返回。即不要使用异常来控制程序操作。如果文件操作意外失败,则抛出异常。如果应用程序需要查找文件并且通常不希望在正常操作中找到它,我不希望调用者捕获异常,而是简单地返回一个布尔值并通过应用程序选择适当的逻辑路径。
您可以返回状态变量,例如枚举、整数或布尔值。问题是调用者必须知道不同的返回值是什么意思。有时 true 意味着它成功,有时它意味着有一个错误。此外,如果调用失败,直接调用者可能不知道该怎么做,需要失败“冒泡”,因为每个方法都失败了,因为它的调用确实如此。
Try-throw-catch 是处理您知道可能会失败的事情的首选模式,并在它失败时控制执行流程:
public void MightFail()
{
//obviously your code will do something a little more meaningful
if(new Random().Next(2) == 0) throw new Exception("I failed");
return;
}
public void RunRiskyMethod()
{
var failures = 0;
var successes = 0;
var totalRuns = 0;
for(var i=1;i<10000;i++)
{
try
{
MightFail();
//if the previous line throws an exception, the below lines will not execute
successes++;
Console.WriteLine("Success!");
}
catch(Exception) //I didn't name the exception because we don't need its info.
{
//These lines ONLY execute if an exception was thrown from within the try block
failures++;
Console.WriteLine("Failure!");
}
finally
{
//this code ALWAYS executes, even if an exception is thrown and not caught
totalRuns++;
}
}
Console.WriteLine(String.Format("{0} Successes, {1} Failures.", successes, failures);
}