c# - 如何强制向 IEquatable 的 Equals 方法添加新的公共属性班级
问题描述
我有包含其他子类的类,所以我已经实现了以递归IEquatable<T>
方式执行自定义方法。Equals
这工作正常,但我在想如果其他开发人员需要向这些类添加新的公共属性,我们希望强制他们也将它们添加到Equals
方法中。我想知道是否有一种简单的方法可以在没有反射的情况下做到这一点?我可以以某种方式利用自定义属性吗?我基本上想将它添加到单元测试套件中,这样构建就会失败。
解决方案
如果您想强制您的相等方法以标准方式构建,也许您可以在运行时使用反射编译它们;
private static Expression Equality(Type propType, MemberExpression thisProp, MemberExpression otherProp)
{
var equatable = typeof(IEquatable<>).MakeGenericType(propType);
var equal = Expression.Equal(thisProp, otherProp);
if (!equatable.IsAssignableFrom(propType))
return equal;
// a == b || (a!=null && a.Equals(b))
return Expression.OrElse(
equal,
Expression.AndAlso(
Expression.NotEqual(thisProp, Expression.Constant(null, propType)),
Expression.Call(thisProp, equatable.GetMethod("Equals"), otherProp)
)
);
}
private static Delegate GenerateEquatable(Type type)
{
var thisParm = Expression.Parameter(type, "a");
var otherParm = Expression.Parameter(type, "b");
return Expression.Lambda(
type.GetProperties()
.Where(prop => prop.CanRead)
.Select(prop => Equality(
prop.PropertyType,
Expression.MakeMemberAccess(thisParm, prop),
Expression.MakeMemberAccess(otherParm, prop)))
.Aggregate((a, b) => Expression.AndAlso(a, b)),
thisParm, otherParm).Compile();
}
public static Func<T, T, bool> GenerateEquatable<T>() where T:IEquatable<T> =>
(Func<T, T, bool>)GenerateEquatable(typeof(T));
public class Foo : IEquatable<Foo>{
private static Func<Foo, Foo, bool> _equals = GenerateEquatable<Foo>();
public bool Equals([AllowNull] Foo other) => other != null && _equals(this, other);
}
推荐阅读
- pandas - 熊猫从外部列表中添加具有最接近值的新列
- django - 延迟保存 Django ImageField 直到对象有 pk
- javascript - websocket对象未在本机反应中连接套接字
- reactjs - React单选按钮无法呈现选中状态
- python - 如何将代理添加到 quickstart.py-python
- json - 如何使用 `pandas.to_sql` 将 `dict` 列推入 Redshift SUPER 类型列?
- php - 在 Laravel 8 的用户表中更改名称列“created_at”和“updated_at”
- pytorch - 如何拥有一个从多个数据集中获取批次的数据加载器,但每个批次只能包含来自一个数据集的元素?
- python - 将变量传入和传出 exec
- postgresql - PostgreSQL:ON CONFLICT DO UPDATE 命令不能再次影响行