繁体   English   中英

自定义异常C#

[英]Custom Exception C#

我想创建自己的自定义Exception(针对我自己的实践),我有Man类,并且我想检查名称(所以它不是空的,null的而且只有英文字符。我不确定是否在做这种权利,1.我是否需要在Custom Exception类或Man's setter中编写处理错误(如果发生)的代码?2.在最佳实践中应在哪里使用“ throw new Exception”?任何有关我的代码的评论/改进都将受到欢迎。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace prog
{
    class Program
    {
        static void Main(string[] args)
        {

            try
            {
                Man p = new Man("Dan");

            }
            catch (Exception e)
            {
                throw new NameNotValidException(e.Message);
            }


        }
}

class Man
{
    private string name;

    public string Name
    {
        get { return name; }
        set
        {
            if (name == "" || name == null)
            {
                throw new NameNotValidException("error");
            }

            name = value;
        }
    }

    public Man(string name)
    {
        this.name = name;
    }

}

class NameNotValidException : Exception
{
    public NameNotValidException()
    {
        Console.WriteLine("Please Write a valid name!");
    }

    public NameNotValidException(string message)
        : base(message)
    {
    }

    public NameNotValidException(string message, Exception inner)
        : base(message, inner)
    {
    }
}

谢谢!

如果要创建自定义异常,只需扩展任何异常类,例如:

class MyCustomException : System.Exception
{}

并且您可以throw new MyCustomException();

当您引发异常时,您会说“嘿,出了点问题!”,因此调用方可以对此做一些事情。 异常的责任是说到底出了什么问题,而不是说如何处理。 因此,您应该删除Console.WriteLine("Please Write a valid name!"); 从例外。 相反,将其放在实际预期该错误的代码中-即您的Main方法。 静态void Main(string [] args){

        try
        {
            Man p = new Man("Dan");
        }
        catch (NameNotValidException e)
        {
            Console.WriteLine("Please Write a valid name! " + e.Message);
        }

还要注意,我在catch块中使用了NameNotValidException ,而不是Exception 通常,您应该在处理错误时尽可能具体-这就是为什么我们首先创建自定义异常=)的原因。 例如,假设您添加了一个Age属性,该属性引发AgeNotValidException。 如果捕获到Exception e ,则会说“请输入一个有效的名称!”。 对于每个错误,包括无效的年龄。 通过分别处理每种异常类型,可以不同地处理每个错误。

关于您的“引发新异常”问题,您正在正确地进行操作:当您无法执行某些操作时,应该引发异常-在这种情况下,由于给定名称无效,因此您无法设置用户名。 但是,您还应该尝试对错误消息进行更具体的说明,以使错误更容易从中恢复:在您的情况下,您可以按照throw new NameNotValidException("Name can't be empty");将其更改为某些内容throw new NameNotValidException("Name can't be empty"); ,因此您不仅可以告诉用户名称无效,还可以告诉用户原因。

  1. 在这种情况下,更合适的是抛出ArgumentNullException 最终使用哪个异常( 您自己的异常ArgumentNullException )无关紧要,并且不会更改下面的代码结构,也不会更改异常的处理方式。
  2. 您想检查value ,而不是setter中的name
  3. 在调用代码处处理异常。 如果调用代码不是为处理异常而设计的,则不要捕获该异常或使用throw来重新throw以保留堆栈跟踪。
  4. 在由于以下原因导致代码失败的位置抛出异常( 在这种情况下为无效值
  5. 请小心您的getter / setter代码,检查错误的值,并绕过构造函数中的setter,在这种情况下,它永远不会引发Exception。

你的男人课。

public class Man {
    public Man(string name)
    {
        // notice capital N for Name so it is set on the property, not the field
        // this will execute the setter for the Name property
        this.Name = name;
    }

    public Man(){} // optional, but do not include the parameterized constructor you had as it sets the private fields directly OR include additional validation

    private string name;
    public string Name
    {
        get { return name; }
        set
        {
            if (string.IsNullOrEmpty(value))
                throw new ArgumentNullException("Name cannot be null or empty");
            name = value;
        }
    }
}

处理异常的调用代码。

try
{
    // use parameterized constructor
    Man p = new Man("Dan"); 

    // or use an initializer
    Man p = new Man{Name = "Dan"}; 

    // the above initializer is actually short for
    Man p = new Man(); 
    p.Name = "Dan"; 
}
catch (ArgumentException e)
{
    Console.WriteLine("Error occurred!! Do something...");
}

如果只想更改消息,则可以使用以下方法: throw new Exception("File check failed!");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM