C#学习之Exception类

C#学习之Exception类

using System;
//Represents error that occur during application execution
//Inheritance:  Object→Exception

//The following example demomstrate a catch block that is defined to handle Arithmetic
//exception errors.Thic catch block also catches DivideByZero exception errors, because
//DevideByZero exception derived from Arithmetic exception and there is no catch block
 explicitly defined for DevideByZero error.

namespace 基类练习之_Exception
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 0;
            try
            {
                int y = 100 / x;
            }
            catch(ArithmeticException excep)
            {
                Console.WriteLine($"Arithmetic Exception Handler:{excep}");
            }
            catch(Exception ex)
            {
                Console.WriteLine($"Generic Exception handler:{ex}");
            }

            // This code example produces the following results:
            // Arithmetic Exception Handler:System.DivideByZeroException: 尝试除以零。
        }
    }
}

Errors and exception

Run-time errors can occur for a variety of reasons.However ,not all errors should be handled as exceptions in your code.Here are some categories of errors that can occur at
run time and the appropriate ways to respond to them.

  • Usage errors
    A usage error represents an error in program logic that can result in anexception.
    However,the error should be addressed not through exception handling but by modifying the faulty code.
    For example,the override of the Object.Equals(Object) mrthod inthe following
    example assume that the obj argument must always be non-null
using System;
namespace 基类练习之_Exception
{
    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public Person(string na)
        {
            this._name = na;
        }
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
        public override bool Equals(object obj)
        {
            // This implementation contains an error in program logic
            // It assums that the  obj argument is not null;
            Person p = (Person)obj;
            return this.Name.Equals(p.Name);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
          try
            {
                Person p1 = new Person("John");
                Person p2 = null;
                // The following throws a NullReferenceException
                Console.WriteLine(p1.Equals(p2));
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadKey();
        }
        // This code example produces the following results:
        // System.NullReferenceException: 未将对象引用设置到对象的实例。
    }
}

The NullReferenceException exceptio that results when obj is null can be eliminated
by modifying the source code to exlplicitly test for null before calling the Object.Equals()
method.The following example conatains corrected source code that handles a null argument.

using System;
namespace 基类练习之_Exception
{
    public class Person
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public Person(string na)
        {
            this._name = na;
        }
        public override int GetHashCode()
        {
            return this.Name.GetHashCode();
        }
        public override bool Equals(object obj)
        {
            // This implementation contains an error in program logic
            // It assums that the  obj argument is not null;
            Person p = (Person)obj;
            if (p is null)
            {
                return false;
            }
            else
            {
                return this.Name.Equals(p.Name);
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Person p1 = new Person("John");
                Person p2 = null;
                // The following throws a NullReferenceException
                Console.WriteLine(p1.Equals(p2));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            Console.ReadKey();
        }
    }
}


Instead of exception handling for usage errors, you can the Debug.Assert() method to
identify usage errors in debug builds.and the Trace.Assert method to identify usage errors
in both debug and release builds.

  • Program errors
    A program error is a run-time error that cannot necessarily be avoided by writing bug-free code.
    In some cases, a program error may reflect an expected or routine error condition. In this case, you may want to avoid using exception handling to deal with the program error and instead retry the operation. For example, if the user is expected to input a date in a particular format, you can parse the date string by calling the DateTime.TryParseExact method, which returns a Boolean value that indicates whether the parse operation succeeded, instead of using the DateTime.ParseExact method, which throws a FormatException exception if the date string cannot be converted to a DateTime value.
using System;
namespace 基类练习之_Exception
{
    class Program
    {
        static void Main(string[] args)
        {
            string str = "1.1r";
            double res;
            bool falg = double.TryParse(str, out res);
            if (falg)
            {
                Console.WriteLine(res);
            }
            else
            {
                Console.WriteLine("转换失败");
            }
            Console.ReadKey();
        }
    }
}
  • System errors
    A system failure is a run-time error that cannot be handled programmatically in a meaningful way.
The following table lists common exceptio types and the conditions under which you would throw them
ExceptionCondition
ArgumentExeptionA non-null argument is passed to a method is invalid
ArgumentNullExceptionAn argument that is passed to a method is null
ArgumentOutOfRangeExceptionAn-argument is outside of the range of valid values
DirectioryNotFoundExceptionPart of a directory is not valid
DevideByZeroExceptionThe denominator is an integer or Decimal division operatio is zero
DriveNotFoundExceptionA drive is unavailable or does not exit
FIleNotFoundExceptionA file is not exception
TimeoutExceptionThe time interval allotted to an operation has expired.
NotImplementedExceptionA method or operation is not implemented.
InvalidOperationExceptionA method call is invalid in an object’s current state.
To define your own exception class:

The following example illustrates the use of a custom exception class. It defines a NotPrimeException exception that is thrown when a client tries to retrieve a sequence of prime numbers by specifying a starting number that is not prime. The exception defines a new property, NonPrime, that returns the non-prime number that caused the exception. Besides implementing a protected parameterless constructor and a constructor with SerializationInfo and StreamingContext parameters for serialization, the NotPrimeException class defines three additional constructors to support the NonPrime property. Each constructor calls a base class constructor in addition to preserving the value of the non-prime number. The NotPrimeException class is also marked with the SerializableAttribute attribute.

The following example makes two calls to the GetPrimesFrom method with non-prime numbers, one of which crosses application domain boundaries. In both cases, the exception is thrown and successfully handled in client code.

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Reflection;
namespace 基类练习之_Exception
{
    [Serializable()]
    public class NotPrimeException:Exception
    {
        private int notAPrime;
        protected NotPrimeException()
            :base()
        { }
        public NotPrimeException(int value)
            : base(String.Format($"{value} is not a prime number"))
        {
            notAPrime = value;
        }

        public NotPrimeException(int value,string message)
            :base(message)
        {
            notAPrime = value;
        }
        public NotPrimeException(int value,string message,Exception innerException)
            :base(message,innerException)
        {
            notAPrime = value;
        }
        public NotPrimeException(SerializationInfo info,StreamingContext context)
            :base(info,context)
        {

        }
        public int NonPrime
        {
            get { return notAPrime; }
        }

    }
    public class PrimeNumberGenerator
    {
        private const int START = 2;
        private int maxUpperBound = 10000000;
        private int upperBound;
        private bool[] primeTable;
        private List<int> primes = new List<int>();

        public PrimeNumberGenerator(int upperBound)
        {
            if(upperBound>maxUpperBound)
            {
                string message = string.Format($"{upperBound} exceeds the maxUpperBound of{maxUpperBound}");
                throw new ArgumentOutOfRangeException(message);
            }
            this.upperBound = upperBound;
            // Create array and mark 0,1 as not prime(True)
            primeTable = new bool[upperBound + 1];
            primeTable[0] = true;
            primeTable[1] = true;

            // Use Sieve of Eratosthenes to determine prime numbers.
            for(int ctr=START;ctr<=(int)Math.Ceiling(Math.Sqrt(upperBound)) ;ctr++)
            {
                if (primeTable[ctr]) continue;
                for(int multiplier=ctr;multiplier<= multiplier/ctr; multiplier++)
                {
                    if (ctr * multiplier <= upperBound) primeTable[ctr * multiplier] = true;
                }

                // Populate array with prime number information
                int index = START;
                while(index!=-1)
                {
                    index = Array.FindIndex(primeTable, index, (flag) => !flag);
                    if(index>=1)
                    {
                        primes.Add(index);
                        index++;
                    }
                }

            }


        }
        
        public int[] GetAllPrimes()
        {
            return primes.ToArray();
        }
        public int[] GetPrimesFrom(int prime)
        {
            int start = primes.FindIndex((value) => value == prime);
            if(start<0)
            {
                throw new NotPrimeException(prime, string.Format($"{prime} is not a prime number"));
            }
            else
            {
                return primes.FindAll((value) => value >= prime).ToArray();
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int limit = 10000000;
            PrimeNumberGenerator primes = new PrimeNumberGenerator(limit);
            int start = 1001;
            try
            {
                int[] values = primes.GetPrimesFrom(start);
                Console.WriteLine($"There are {values.Length} prime numbers from {start} to {limit}");


            }
            catch(NotPrimeException ex)
            {
                Console.WriteLine($"{ex.NonPrime} is not prime.");
                Console.WriteLine( ex);
                Console.WriteLine("================");
            }

            AppDomain domain = AppDomain.CreateDomain("Domain2");
            PrimeNumberGenerator gen=(PrimeNumberGenerator)domain.CreateInstanceAndUnwrap(typeof(Program).Assembly.FullName,"PrimeNumberGenerator",
            true,BindingFlags.Default,null,new Object[] { 1000000 },null,null);


            try
            {
                start = 100;
                Console.WriteLine(gen.GetPrimesFrom(start));
            }
            catch(NotPrimeException ex)
            {
                Console.WriteLine($"{ex.NonPrime} is not a prime");
                Console.WriteLine(ex);
                Console.WriteLine("================");
            }
            Console.ReadKey();
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值