如何用C#从派生类中的构造函数捕获异常?
我想知道如何从C#派生类中的构造函数捕获异常。例如:如何用C#从派生类中的构造函数捕获异常?,c#,.net,exception-handling,constructor,C#,.net,Exception Handling,Constructor,我想知道如何从C#派生类中的构造函数捕获异常。例如: public class MyClassA { public MyClassA() { //Do the work if (failed) { throw new Exception("My exception"); } } } public class MyClassB : MyClassA { public MyCla
public class MyClassA
{
public MyClassA()
{
//Do the work
if (failed)
{
throw new Exception("My exception");
}
}
}
public class MyClassB : MyClassA
{
public MyClassB()
{
//How to catch exception from a constructor in MyClassA?
}
}
1) 解决方法:在派生的:
class MyClassB : MyClassA
{
public static MyClassB Create()
{
try
{
return new MyClassB();
}
catch
{
// try to handle
}
}
}
2) 或者在基中创建一个类似的函数,而不是在构造函数中,而是在方法中:
3) 或者提供一个可覆盖的策略来处理失败状态:
class MyClassA
{
public MyClassA
{
if (failed)
OnFail();
}
protected virtual void OnFail()
{
throw new Exception();
}
}
class MyClassB : MyClassA
{
protected override void OnFail()
{
// don't throw
}
}
我想我会这样处理
public class MyClassA
{
protected bool test;
public MyClassA()
{
//Do the work
if (true)
{
test = true;
return;
}
}
}
public class MyClassB : MyClassA
{
public MyClassB()
{
if (base.test)
{
//How to catch exception from a constructor in MyClassA?
}
}
}
甚至不要试图找出如何做到这一点。如果基类构造函数抛出异常,则表示基类处于错误状态。如果基类处于错误状态,则表示派生类处于错误状态。构造函数的要点是使对象进入可用状态。它失败了。出去 我用静态方法解决了同样的问题:
public class PdfReaderExtended : PdfReader
{
public PdfReaderExtended(string filename) : base(filename)
{
}
public static PdfReaderExtended CreateInstance(string filename)
{
var name = Path.GetFileName(filename);
try
{
return new PdfReaderExtended(filename);
}
catch (Exception ex)
{
throw new ClientException("Oops");
}
}
}
我担心这是不可能的。可能只有我一个人,但我一直试图避免施工人员做“工作”。我认为这是一种非常不寻常的行为,可能会给不熟悉代码库的开发人员带来麻烦。与其他一些OOP语言不同,从C#构造函数抛出异常具有定义良好的行为。捕获它也有很好的定义,需要对新操作符进行try/catch操作。所以至少比你希望的位置高一层。在派生类中捕获它当然不起作用,这是一个没有地下室的纸牌屋。抛出异常非常昂贵。这是一个更好的选择approach@HasTaiar:这不是真的。即使在C++中。谢谢abatishchev,即使在你提供的链接中,这仍然是有争议的。。干杯:)我不同意。如果您的基类不能被构造,那么代码就有很大的问题。我将把建立对象内部状态的逻辑移到方法调用中,并将基本构造留给方法调用。这可以让你更好地控制你的代码,你可以把它倒过来。在这种情况下,基类构造得很好,但派生类抛出。这通常是一个一次性对象的问题,在这个对象中,基类希望被释放(因为它的构造函数工作),但不会是因为派生类中的构造函数失败。@Yaur:你在说什么?阅读代码:
MyClassB:MyClassA
。我的坏。将此错误理解为一个更有趣的问题:如何使用工厂方法从基类继承(您的选项#2)?+1表示#3。我有一个通用的基工厂类,它使用反射从一个名称实例化一个具体的类。通过重写派生的具体工厂类上的虚方法,我可以在基类出错时实现自定义错误处理。
public class PdfReaderExtended : PdfReader
{
public PdfReaderExtended(string filename) : base(filename)
{
}
public static PdfReaderExtended CreateInstance(string filename)
{
var name = Path.GetFileName(filename);
try
{
return new PdfReaderExtended(filename);
}
catch (Exception ex)
{
throw new ClientException("Oops");
}
}
}