访问类成员的类型安全枚举
本文关键字:类型安全 枚举 成员 访问 | 更新日期: 2023-09-27 18:33:45
我的类MyClass<t>
有以下方法
private static bool TypeHasProperty(string NameOfPropertyToMatch)
{
var properties = typeof(t).GetProperties();
var requiredProperty = properties.First(
a => a.Name == NameOfPropertyToMatch);
if (requiredProperty == null)
{
return false
};
return true;
}
这在静态方法开始时调用:
MyClass<t>.SendToJavaScript(t InstanceOfType, string NameOfPropertyWithinType)
.
在继续之前确保InstanceOfType
实际上具有该名称的属性,否则在 waaaaay 下行之前不会引发异常(此信息最终将被序列化并发送到Javascript应用程序,该应用程序需要知道要访问哪个属性才能完成其工作(。
我想要一种很好的、类型安全的方式来调用该方法,如果我决定稍后更改我的属性名称,该方法不会导致验证失败。
例如,我不想这样称呼它:
MyClass<Person>.SendToJavaScript(MyPerson, "Name")
因为如果我决定在Person
课上将Name
改为LastName,
,我必须确保进来并更改该魔术字符串。
我想要的是这样的:
MeClass<Person>.SendToJavaScript(
MyPerson,
TypeOf(Person).Properties.Name.ToString())
这样,如果我使用重构将Name
更改为LastName
,IDE 将扫描那里并更改我的调用。
有这样的事情存在吗?还是我在重构时只需要小心?(我爱我一些F2
(
我们在代码中使用类似的东西:
private static bool TypeHasProperty<P>(Expression<Func<T, P>> accessor)
{
var propertyName = ((MemberExpression)accessor.Body).Member.Name;
var properties = typeof(T).GetProperties();
return properties.Any(a => a.Name == propertyName);
}
使用它:
class Foo
{
public int Baz { get; set; }
}
MyClass<Foo>.TypeHasProperty(f => f.Baz);
编辑:更改了查询以使用Any()
因为它可以更好地表达您实际想要执行的操作(是否存在具有给定名称的属性?
请注意,如果未找到匹配项,First()
将抛出。
试试这个:
MeClass<Person>.SendToJavaScript(MyPerson, x => x.Name);
然后:
private static bool TypeHasProperty(Expression propertyExpression)
{
var expression = GetMemberInfo(propertyExpression);
string name = expression.Member.Name;
return typeof(t).GetProperty(name) != null;
}
private static MemberExpression GetMemberInfo(Expression method)
{
LambdaExpression lambda = method as LambdaExpression;
if (lambda == null)
throw new ArgumentNullException("method");
MemberExpression memberExpr = null;
if (lambda.Body.NodeType == ExpressionType.Convert)
{
memberExpr =
((UnaryExpression)lambda.Body).Operand as MemberExpression;
}
else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
{
memberExpr = lambda.Body as MemberExpression;
}
if (memberExpr == null)
throw new ArgumentException("method");
return memberExpr;
}
从这里无耻地获取:从 lambda 表达式中检索属性名称
但这是一个稍微不同的问题,所以我发布了一个完整的答案。
我刚刚注意到,在我提供的链接中,第二个答案要简单得多。克里斯·乌埃(ChrisWue'a(在此线程中的答案中对此进行了介绍。