In short, you can't solve your problem (prevent IEnumerable<>
from being passed to a generic method) with generics. This is because you can't have negative generic constraints (ie., everything except someClass
). The only reason that generic constraints exists is to allow the compiler to know what signature to expect on the generic type. It is not to provide the developer with design-time cues.
Aside from any unspecified external requirements, you can define your generic type at the interface, rather than the method. This does not ensure that T
cannot implement IEnumerable<>
; however, it does ensure that ValidateList
must accept a list of whatever is passed to Validate
. This means that T
can be an array, but that would force ValidateList
to accept an array of arrays.
If you leave the generic types at the method level, even though they both have an generic type named T
, those types don't actually have anything to do with each other.
Generic type defined at interface.
public interface ISomeInterface<T>
{
ValidationResult Validate(T t);
IList<ValidationResult> ValidateList(IEnumerable<T> entities);
}
This would be implemented like:
public class SomeClass<T> : ISomeInterface<T>
{
ValidationResult Validate(T t)
{
// Do something ...
}
IList<ValidationResult> ValidateList(IEnumerable<T> entities)
{
// Do something ...
}
}
And used like this:
var myInstance = new SomeClass<int>();
int obj = 5;
int arr = new [] {1,2,3};
myInstance.Validate(obj);
myInstance.ValidateList(arr);
myInstance.Validate(arr); // should throw compiler error