如何将其重构为通用表达式?
How to refactor this into generic Expression?
如何将此 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
结果。
您可以直接调用现有的方法
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>
上调用它?
你可以,但这不是维护类型安全的好方法。
或者,您可以这样做:
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));
使用反射可以后期绑定到所需的 属性:
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));
}
(以上假定命名的 属性 始终存在并且永远不会为空)
如何将此 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
结果。
您可以直接调用现有的方法
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>
上调用它?
你可以,但这不是维护类型安全的好方法。 或者,您可以这样做:
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));
使用反射可以后期绑定到所需的 属性:
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));
}
(以上假定命名的 属性 始终存在并且永远不会为空)