C# 创建对象时在构造函数中引发异常或预先验证参数?

C# 创建对象时在构造函数中引发异常或预先验证参数?,c#,exception,C#,Exception,我希望对象实例化经常出现一个错误的参数 我应该吗 A首先检查参数,然后创建对象(如果有效)。 B创建由try/catch块包围的对象,并让构造函数在无效时抛出异常 有什么理由选择A或B而不是另一个吗?还有一个选择是使用无参数构造函数和返回true或false的初始化方法 这样: 可以手动或使用对象池多次重复使用同一对象 验证逻辑将被封装 所以你的班级可以是这样的: class Foo { private Bar m_bar; public Foo() {

我希望对象实例化经常出现一个错误的参数

我应该吗 A首先检查参数,然后创建对象(如果有效)。 B创建由try/catch块包围的对象,并让构造函数在无效时抛出异常


有什么理由选择A或B而不是另一个吗?

还有一个选择是使用无参数构造函数和返回true或false的初始化方法

这样:

可以手动或使用对象池多次重复使用同一对象 验证逻辑将被封装 所以你的班级可以是这样的:

class Foo
{
    private Bar m_bar;

    public Foo()
    {
        // do nothing here
    }

    public bool Initialize(Bar bar)
    {
        if (bar == null) // validation logic here
            return false;

        m_bar = bar;
        return true;
    }
}

还有一种选择是使用无参数构造函数和返回true或false的初始化方法

这样:

可以手动或使用对象池多次重复使用同一对象 验证逻辑将被封装 所以你的班级可以是这样的:

class Foo
{
    private Bar m_bar;

    public Foo()
    {
        // do nothing here
    }

    public bool Initialize(Bar bar)
    {
        if (bar == null) // validation logic here
            return false;

        m_bar = bar;
        return true;
    }
}

如果只有几个一个或两个参数,请使用或静态方法进行创建,尽量避免构造函数中出现异常

或者,如果有许多或可选参数,请使用


此外,您还可以公开验证方法,因此谨慎的客户机可能会首先检查。

如果只有少数一个或两个参数,请使用或静态方法进行创建,尽量避免构造函数中出现异常

class Check
{
    private Some getsome;

    public Some GetSome
    {
       get
       {
            return getsome;
       }
       set
       {
           if(value != null)   //or any other logic you want
              getsome = value; //if another logic like value < 10
           else                //you can throw - throw new ArgumentException - for example
              throw new ArgumentNullException("value");
       }
    }

    public Check()
    {

    }

}
或者,如果有许多或可选参数,请使用

此外,您还可以公开验证方法,因此谨慎的客户机可能会首先进行检查

class Check
{
    private Some getsome;

    public Some GetSome
    {
       get
       {
            return getsome;
       }
       set
       {
           if(value != null)   //or any other logic you want
              getsome = value; //if another logic like value < 10
           else                //you can throw - throw new ArgumentException - for example
              throw new ArgumentNullException("value");
       }
    }

    public Check()
    {

    }

}
请记住,这里的承包商GetSome是公共财产,因此您不会错过检查


记住这里的constructor GetSome是公共属性,所以你不会错过检查

检查比抛出好,异常是昂贵的。只有抛出异常才是昂贵的,对吗?还是我错了?所以,如果它几乎从未命中,那么尝试捕获可能会更快?检查比抛出好,异常是昂贵的。但只有抛出异常时,异常才是昂贵的,对吗?还是我错了?因此,如果它几乎从不命中,那么try-catch可能会更快?为什么要在构造函数中避免异常?@Konrad,根据Ops的开头语句,我希望对象实例化经常出现一个错误的参数-异常是针对意外或异常情况的。如果合适,状态确实会从实例构造函数引发异常。我也许应该强调try-in,以避免构造函数中出现异常。验证是一个交叉、边界问题,隐藏在构造函数逻辑中,无法重用。。。。如果预期参数无效,请拥有实例化代码和构造函数,然后尝试catch,因为验证显然是错误的。亲自申请;我不希望从构造中发现异常,构造函数不仅仅是设置字段,而是在以后的使用中失败——所以更喜欢快速失败,静态/工厂方法是有利的。旁注;在没有内存管理的语言中,这是一种反模式,因为您经常需要捕获抛出的异常,以便在重试之前清理所有资源。下面是为什么要在构造函数中避免异常?@Konrad,根据Ops的开场白,我希望对象实例化经常出现一个错误的参数——异常是针对意外或异常情况的。如果合适,状态确实会从实例构造函数引发异常。我也许应该强调try-in,以避免构造函数中出现异常。验证是一个交叉、边界问题,隐藏在构造函数逻辑中,无法重用。。。。如果预期参数无效,请拥有实例化代码和构造函数,然后尝试catch,因为验证显然是错误的。亲自申请;我不希望从构造中发现异常,构造函数不仅仅是设置字段,而是在以后的使用中失败——所以更喜欢快速失败,静态/工厂方法是有利的。旁注;在没有内存管理的语言中,这是一种反模式,因为您经常需要捕获抛出的异常,以便在重新抛出之前清理所有的资源