开发者

What is the appropriate exception to throw for an Object being passed in and needing to be cast to the generic parameter?

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);
    }
}

Not sure what the appropriate exception he开发者_运维百科re is... ArgumentException, InvalidCastException, etc?


It's a problem with the argument, so ArgumentException. You haven't actually done the cast, so InvalidCastException is not appropriate.


Consider the example of IList, which supports Add operations using type object. When implemented by the generic List<T>, you get an ArgumentException for invalid types.

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

Result:

ArgumentException: The value "A" is not of type "System.Int32" and cannot be used in this generic collection.Parameter name: value

In examples like this, I might tend to follow the precedents set by BCL classes unless there are compelling arguments against it.


I would consider making a generic interface:

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

Then implement like so:

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

If you can't go with that pattern (because you want to be able to pass any type in), then I would suggest going with a context specific exception for that class:

 public class InvalidMyClassInputException : ApplicationException
 {
      public InvalidMyClassInputException(object obj)
         : base("An invalid call to DoSomething was made with object of type: " + obj.GetType().Name)
      {
      }
 }


Whenever a cast causes an exception (or if something cannot be cast), a InvalidCastException is appropriate.

However, re-architecting your code may be a better solution, and allow compile-time checking:

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

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

        SomeOtherFunc((T)obj);
    }
}

Then you don't even need to check because the environment and/ or compiler is doing it for you, which lets your code be much more simple.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜