问题
I have two generic save methods in a repository class:
public void Save<T>(T entity)
{
_session.Save(entity);
}
public void Save<T>(IEnumerable<T> entities)
{
foreach (var item in entities)
{
_session.Save(item);
}
}
However, when I use Save(collection)
(which infers the type automatically), it recognizes it as a T
rather than IEnumerable<T>
and tries to save it using the first method.
How do I write this save method(s) so that it can handle either case, without me having to explicitly provide the type?
回答1:
Put the type parameter at the class level on your repository instead of at the method level, this way the overload will not be ambiguous.
class Repo<T>
{
public void Save(T entity)
{
_session.Save(entity);
}
public void Save(IEnumerable<T> entities)
{
foreach (var item in entities)
{
_session.Save(item);
}
}
}
You'd use it like this:
var repo = new Repo<Person>();
var p = new Person();
repo.Save(p);
var ps = new Person[] { p };
repo.Save(ps);
回答2:
You can't rely on type inference for this specific case. <T>(T)
will satisfy any type, so the inference won't continue searching to find more specific constraints which still meet the signature.
回答3:
Whjy bother with overloaded methods?, isn't better to do it like:
public void Save<T>(T entity)
{
if (T is IEnumerable)
{
foreach (var item in entity)
_session..Save(item);
} else {
_session.Save(entity);
}
}
回答4:
You can use it like this also:
public void Save<T>(T entity)
{
if (typeof(T).GetInterfaces().Contains(typeof(IEnumerable)))
{
SaveEnumerable(entity as IEnumerable);
}
else
{
_session.Save(entity);
}
}
public void SaveEnumerable(IEnumerable entities)
{
foreach (var item in entities)
{
_session.Save(item);
}
}
Hope this helps!!
来源:https://stackoverflow.com/questions/1931810/how-do-i-write-a-generic-save-method-that-handles-single-objects-and-collectio