Listing 1: Creating the ThrowsAttribute

[AttributeUsage(AttributeTargets.Method |
     AttributeTargets.Property, AllowMultiple = true,
     Inherited = true)]
public sealed class ThrowsAttribute : Attribute
{
    private const string ERROR_NOT_SUBCLASS = 
        "The given type is not an Exception type.";
    private const string PARAM_EXCEPTION_TYPE = 
        "exceptionType";

    private Type exceptionType = null;

    private ThrowsAttribute() : base() {}

    public ThrowsAttribute(Type exceptionType) : base()
    {
        if(exceptionType == null)
        {
            throw new ArgumentNullException(
                PARAM_EXCEPTION_TYPE);
					   }

        Type baseExceptionType = typeof(Exception);
        if(exceptionType != baseExceptionType &&
            exceptionType.IsSubclassOf(baseExceptionType) == false)
        {
            throw new ArgumentException(
                ERROR_NOT_SUBCLASS, 
                PARAM_EXCEPTION_TYPE);
        }

        this.exceptionType = exceptionType;
    }

    public Type ExceptionType
    {
        get
        {
            return this.exceptionType;
        }
    }
}

internal class DangerousMethodClass
{
    [Throws(typeof(InvalidCastException))]
    public void InnocentMethod()
    {
        throw new InvalidCastException();
    }
}