You can't. As mentioned in comments, List<> is a class. Restricting it to classes will include it.
This is an unfortunate case where you'll probably have to simply rely on the contract being used by calling code, and throw an exception for invalid arguments.
public static string GetName<T>(T Object)
{
if(Object is IEnumerable) throw new ArgumentException();
xxxxxxx
}
Another option might be to add an overload that takes an IEnumerable. It's not super pretty, and you might not need it, but at least then the compiler will choose that and return something appropriate.
public static IEnumerable<string> GetName<T>(IEnumerable<T> Objects)
{
return Objects.Select(GetName);
}
Be careful with this, though, because it can sometimes be difficult to predict (or rather, to remember to predict) which one will be called.
List<int> ints = new List<int>();
GetName(ints); // calls the IEnumerable version
object intsObj = (object)ints;
GetName(intsObj); // calls the non-IEnumerable version.
More generally speaking, though, it sounds like you might be setting up a less-than-ideal contract here. If you're doing something like this with unfiltered generics, you'll probably want to be able to handle collections in it as well, and indeed I'm not sure why you wouldn't be able to. They're objects just like anything else.
If you are trying to restrict it, you'll probably want an interface or base class from which all objects passed to this method must be inherited. That will significantly cut down your options for passing .NET classes in, but I can't imagine what use those would have anyway, if you need to get a "name" from something.
If you go that route, you have two options:
- Restrict the parameter itself
- Restrict the generic argument
The choice there depends on the contents and return type of the method, but I'd probably go with the former.
public static string GetName<T>(IObjectWithName Object)
{
return Object.Name;
}
That's not particularly interesting as an example, though, so here's how you would restrict the generics.
public static string GetName<T>(T Object)
where T : IObjectWithName
{
return Object.Name;
}
Just remember that your object needs to implement that interface--you can't pass a DateTime, for instance, to this method and expect it to work. If you expect "random" input like that, you'll probably need to set yourself up to receive collection types as well.
I should mention, just for good practice, that naming your parameters Object is not a good habit. That's a keyword (or rather, a System-level type) in C#. So you could wind up with conflicts.
IHaveName.if (T.GetType().Equals(typeof(List))) { throw new InvalidOperationsException(); };