Что является подходящим исключением для объекта Object, передаваемого и нуждающегося в приведении к универсальному параметру? - PullRequest
4 голосов
/ 16 сентября 2011
public IPredefinedInterface
{
    void DoSomething(Object obj);
}

public class MyClass<T> : IPredefinedInterface
{
    public void DoSomething(Object obj)
    {
        if (!(obj is T)) throw new ???

        SomeOtherFunc((T)obj);
    }
}

Не знаете, какое здесь уместное исключение ... ArgumentException, InvalidCastException и т. Д.?

Ответы [ 4 ]

10 голосов
/ 16 сентября 2011

Это проблема с аргументом, поэтому ArgumentException. Вы на самом деле не сделали актерский состав, поэтому InvalidCastException не подходит.

5 голосов
/ 16 сентября 2011

Рассмотрим пример IList, который поддерживает Add операции с использованием типа object. При реализации универсального List<T> вы получаете ArgumentException для недопустимых типов.

var list = new List<int>();
var ilist = list as IList;
ilist.Add("A");

Результат:

ArgumentException: значение «A» не относится к типу «System.Int32» и не может использоваться в этой универсальной коллекции. Имя параметра: значение

В подобных примерах я мог бы стремиться следовать прецедентам, установленным классами BCL, если нет веских аргументов против этого.

1 голос
/ 16 сентября 2011

Я бы рассмотрел создание универсального интерфейса:

 public interface IPredefinedInterface<T>
 {
       void DoSomething(T obj)
 }

Затем реализовать так:

 public clas MyClass<T> : IPredefinedInterface<T>
 {
      public void DoSomething(T obj)
      {
           // It's now always T, eliminating the need for an exception
      }
 }

Если вы не можете использовать этот шаблон (потому что хотите иметь возможность передавать любой тип), то я бы предложил перейти с контекстно-зависимым исключением для этого класса:

 public class InvalidMyClassInputException : ApplicationException
 {
      public InvalidMyClassInputException(object obj)
         : base("An invalid call to DoSomething was made with object of type: " + obj.GetType().Name)
      {
      }
 }
0 голосов
/ 16 сентября 2011

Всякий раз, когда приведение вызывает исключение (или если что-либо не может быть приведено), уместно InvalidCastException.

Тем не менее, ре-архитектура вашего кода может быть лучшим решением и позволяет проверять время компиляции:

public IPredefinedInterface<T>
{
    void DoSomething(T obj);
}

public class MyClass<T> : IPredefinedInterface<T>
{
    public void DoSomething(T obj)
    {

        SomeOtherFunc((T)obj);
    }
}

Тогда вам даже не нужно проверять, потому что среда и / или компилятор делает это за вас, что делает ваш код намного проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...