Заставить класс, полученный из абстрактного класса, реализовать конструктор - PullRequest
0 голосов
/ 22 марта 2019

У меня есть пользовательское исключение, которое выглядит следующим образом:

public abstract class MyException : Exception
{
    public MyException()
    {
    }

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

    public MyException(string message, Exception inner) : base(message, inner)
    {

    }

    public abstract HttpStatusCode GetHttpStatusCode();
}

И производный класс:

public class ForbiddenException : MyException
{
    public override HttpStatusCode GetHttpStatusCode()
    {
        return HttpStatusCode.Forbidden;
    }
}

Я хочу, чтобы производные классы либо использовали, либо были вынуждены реализовать форматы конструктора в абстрактном классе.

В настоящее время, используя вышеупомянутое, когда я пытаюсь создать ForbiddenException, я получаю следующую ошибку:

throw new ForbiddenException("Request forbidden");

ForbiddenException does not contain a constructor that takes 1 arguments

Я мог бы вручную поместить конструкторы в каждый производный класс MyException, но это подвержено ошибкам + повторение.

Любой совет будет оценен.

1 Ответ

0 голосов
/ 22 марта 2019

Если вы хотите избежать копирования и вставки / ошибок при переписывании, подумайте об использовании текстового шаблона.Я поместил это в шаблон .tt в моей библиотеке классов игрушек, в который я также скопировал ваш MyException в:

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using System;

namespace ClassLibrary2
{

<# StandardConstructors("public","ForbiddenException","MyException"); #>

}
<#+
  public void StandardConstructors(string modifiers,
       string derivedException, string baseException)
    {
        Write(modifiers);
        Write(" partial class ");
        Write(derivedException);
        Write(":");
        WriteLine(baseException);
        WriteLine("{");

        Write("\tpublic ");
        Write(derivedException);
        WriteLine("() {}");

        Write("\tpublic ");
        Write(derivedException);
        WriteLine("(string message):base(message)");
        WriteLine("\t{}");

        Write("\tpublic ");
        Write(derivedException);
        WriteLine("(string message, Exception inner):base(message,inner)");
        WriteLine("\t{}");

        WriteLine("}");
    }
#>

Единственная ошибка, которую я сразу получаю, это то, что я не реализовал GetHttpStatusCode но я ожидаю, что вы будете писать это в отдельном файле, который также определяет тот же частичный класс ForbiddenException.Каждое новое производное исключение требует от вас добавления еще одной строки StandardConstructors в файл шаблона.Гораздо менее подвержен ошибкам.

Конечно, вы можете сделать это настолько изящным, насколько захотите, я просто написал это с нуля за несколько минут 1 .

Этоодин из приведенных выше шаблонов производит:

using System;

namespace ClassLibrary2
{

public partial class ForbiddenException:MyException
{
    public ForbiddenException() {}
    public ForbiddenException(string message):base(message)
    {}
    public ForbiddenException(string message, Exception inner):base(message,inner)
    {}
}

}

Не красиво, но это не обязательно - это сгенерированный код.


1 Например, если вкладки/ spacing действительно раздражает вас, но также если вы хотите иметь больше контроля над модификаторами и т. д.

...