C# 如何处理非法参数的验证

C# 如何处理非法参数的验证,c#,validation,exception,C#,Validation,Exception,我知道这个问题已经在网站上解决了。不过,有很多不同的观点,我想更深入地理解,以了解如何面对某些特殊情况。 假设我有以下代码。我会用C写,虽然这不是一个严格相关的C问题 class Player { private int dexterity; public int Dexterity{ get => dexterity; set{ //Here I need to validate: problem 2

我知道这个问题已经在网站上解决了。不过,有很多不同的观点,我想更深入地理解,以了解如何面对某些特殊情况。 假设我有以下代码。我会用C写,虽然这不是一个严格相关的C问题

class Player
{
    private int dexterity;
    public int Dexterity{
        get => dexterity;
        set{
           //Here I need to validate: problem 2
           dexterity = value;
           UpdateArmorClass(); //Armor class should be modified any time dex is
        }
    private int armorClass;

    public Player(int dex){
        Dexterity = dex;
    }

    private void UpdateArmorClass(){
        //Should I validate here? Problem 3
        armorClass = 10 + Dexterity;
    }
}
//Here is main with user input: problem 1
让我们假设一个用户被要求输入它的dexture,,它必须是非负的,以创建它的字符。现在我面临三种情况:

  • 问题1:用户输入验证:环顾四周,我确信我从不使用异常来验证用户输入,因为这是经常发生的事情。我想我可以通过使用一个布尔值isValid来解决这个问题,如果值为false,则再次要求用户输入他的值。这是一个好的解决方案吗
  • 问题2:构造函数中的验证:好吧,它实际上不在构造函数中,我把它放在灵巧度设置器中,它将由构造函数调用。先验地,不需要检查这一点,因为如果用户输入已经过验证,那么数据将是正确的。不过,我可能会在代码中的其他地方创建播放器(所以我想检查程序员级别而不是用户级别),而且决不允许灵活性为负值。在这里,我面临着一个大难题:是否使用异常? 我个人会使用它们来阻止程序生成无效对象。尽管如此,由于异常的昂贵性,许多人不鼓励使用异常。我能想到的唯一解决方案是,只要给定的值出错,就给出默认值。不过,对我来说,这似乎是一个棘手的解决方案,因为程序将不受干扰地进行,并且我不知道已经设置了默认值(这对于我的情况可能是错误的)。所以,真正的问题是:我是否应该在构造函数(或setter)中使用异常来处理这样的情况
  • 问题3:方法验证:现在我知道armorClass也不应该被允许为负数。在我的情况下,我有一个私有方法,可以在修改敏捷性时更新armorclass。因此,这里确实没有必要再次验证。现在假设我创建了另一个类,用于进行简单的战斗,我在本文末尾展示了这个方法,它计算了被击中的概率。它期望获得一些armorClass值,尽管我可能是另一个程序员,不知道播放器中的armorClass是否已经过验证。所以我检查它是否是非负的。为这样一个检查抛出一个异常似乎很难,但是如果我检查它的非负性,当armorClass为负时,我必须返回一个默认值,这看起来很棘手在这种情况下我该怎么办?
最后一种方法是:

public float Hit(int armorClass){
    if(armorClass >=0) //calculate probability of being hit
    //return probability
}
额外问题(当然与前面的问题相关):实例化一个新的异常真的那么昂贵吗?还是仅仅是试抓部分?对我来说,这就像实例化一个新对象,仅此而已。不过,我可能是错的,这就是为什么很多人说如果不是真的需要,就不应该使用异常

在这里,我面临着一个大难题:是否使用异常?我想要 亲自使用它们来阻止程序生成无效的 对象尽管如此,许多人还是不鼓励使用异常,因为它具有 昂贵

使用异常。只有在引发异常时,异常才会很昂贵,而且引发异常总比最终导致对象损坏要好。若您的值来自用户输入,那个么在您从用户处获取无效值的地方分别处理这些值。这样,您就可以从代码中安全地调用这些methods/set值,并且在用户输入无效值时不会引发异常。此外,有时您可能希望让用户使用一些特殊值,但不允许用户输入这些值

问题3: 如果您的私有字段总是在设置之前经过验证,那么在get上检查它是否有效就没有意义了。在代码示例中,将
10
添加到任何非负数将始终返回非负值

奖金问题: 所有引发的异常都必须在某个地方处理,所以我认为引发异常的部分是昂贵的,还是捕获部分并不重要

在这里,我面临着一个大难题:是否使用异常?我想要 亲自使用它们来阻止程序生成无效的 对象尽管如此,许多人还是不鼓励使用异常,因为它具有 昂贵

使用异常。只有在引发异常时,异常才会很昂贵,而且引发异常总比最终导致对象损坏要好。若您的值来自用户输入,那个么在您从用户处获取无效值的地方分别处理这些值。这样,您就可以从代码中安全地调用这些methods/set值,并且在用户输入无效值时不会引发异常。此外,有时您可能希望让用户使用一些特殊值,但不允许用户输入这些值

问题3: 如果您的私有字段总是在设置之前经过验证,那么在get上检查它是否有效就没有意义了。在代码示例中,将
10
添加到任何非负数将始终返回非负值

奖金问题:
所有引发的异常都必须在某个地方处理,因此我认为无论是昂贵的引发异常部分,还是捕获异常部分都无关紧要。

非常感谢您的明确回答!最后一个例子(在另一个类中使用public方法)怎么样?你能检查一下那里的装甲等级吗?比如,如果armorclass为正:计算概率;否则,不执行任何操作/返回默认值(例如0)。我总是觉得很难想象这种验证的后果。不过,在这种情况下,它似乎是唯一的解决方案。嗯,它是一种公共方法,因此假设您的参数始终有效可能不是最好的主意。具体做什么取决于逻辑