如何将此C#代码重构为一个通用GetBy(string property, string search)
方法?
public MyModel GetByName(string name)
{
return GetAll().SingleOrDefault(d => string.Equals(d.Name, name, StringComparison.OrdinalIgnoreCase));
}
public MyModel GetByUrl(string url)
{
return GetAll().SingleOrDefault(d => string.Equals(d.Url, url, StringComparison.OrdinalIgnoreCase));
}
GetAll()
会返回MyModel列表,因此这也是一个问题,它不是IQueryable
结果。
答案 0 :(得分:3)
你可以,但它不是保持类型安全的好方法。 或者,您可以这样做:
public MyModel GetBy<T>(Func<MyModel, T> property, T value) where T : IEquatable<T> {
return GetAll().SingleOrDefault(d => property(d).Equals(value));
}
GetBy(m => m.Name, "Foo");
或者:
public MyModel GetBy(Func<MyModel, bool> predicate) {
return GetAll().SingleOrDefault(predicate);
}
GetBy(m => m.Name.Equals("Foo", StringComparison.OrdinalIgnoreCase));
答案 1 :(得分:0)
使用Reflection可以后期绑定到所需的属性:
public MyModel GetBy(string name, string value)
{
var getter = typeof(MyModel).GetProperty(name).GetGetMethod();
return GetAll().SingleOrDefault(d =>
string.Equals(getter.Invoke(d, null).ToString(), value, StringComparison.OrdinalIgnoreCase));
}
(以上假设命名属性始终存在且永远不为空)
答案 2 :(得分:-1)
您可以调用现有方法
public MyModel GetBy(string property, string search)
{
switch (property) {
case nameof(MyModel.Name):
return GetByName(search);
case nameof(MyModel.Url):
return GetByUrl(search);
default:
throw new ArgumentException($"Unsupported property \"{property}\"");
}
}
当然,你可以内联这两个功能。
但为什么要在GetAll
而不是Set<MyModel>
上调用它?