通过lambda表达式传入时,是否有更好的方法来获取属性名称?这是我现在拥有的.
例如.
GetSortingInfo<User>(u => u.UserId);
Run Code Online (Sandbox Code Playgroud)
只有当属性是字符串时,它才能将其作为元素表达式进行处理.因为不是所有属性都是字符串我必须使用对象,但它会返回一个单一表达式.
public static RouteValueDictionary GetInfo<T>(this HtmlHelper html,
Expression<Func<T, object>> action) where T : class
{
var expression = GetMemberInfo(action);
string name = expression.Member.Name;
return GetInfo(html, name);
}
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 …Run Code Online (Sandbox Code Playgroud) (参见下面我使用我接受的答案创建的解决方案)
我正在尝试提高一些涉及反射的代码的可维护性.该应用程序有一个.NET Remoting接口,公开(除此之外)一个名为Execute的方法,用于访问未包含在其已发布的远程接口中的应用程序部分.
以下是应用程序如何指定可通过Execute访问的属性(本例中为静态属性):
RemoteMgr.ExposeProperty("SomeSecret", typeof(SomeClass), "SomeProperty");
Run Code Online (Sandbox Code Playgroud)
所以远程用户可以调用:
string response = remoteObject.Execute("SomeSecret");
Run Code Online (Sandbox Code Playgroud)
并且应用程序将使用反射来查找SomeClass.SomeProperty并将其值作为字符串返回.
不幸的是,如果有人重命名SomeProperty并忘记更改ExposeProperty()的第3个parm,它会破坏这种机制.
我需要相当于:
SomeClass.SomeProperty.GetTheNameOfThisPropertyAsAString()
Run Code Online (Sandbox Code Playgroud)
在ExposeProperty中用作第三个parm,因此重构工具将负责重命名.
有没有办法做到这一点?提前致谢.
好的,这是我最终创建的内容(根据我选择的答案和他引用的问题):
// <summary>
// Get the name of a static or instance property from a property access lambda.
// </summary>
// <typeparam name="T">Type of the property</typeparam>
// <param name="propertyLambda">lambda expression of the form: '() => Class.Property' or '() => object.Property'</param>
// <returns>The name of the property</returns>
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
{
var me = propertyLambda.Body as MemberExpression;
if (me == null)
{ …Run Code Online (Sandbox Code Playgroud) 那里有大量的反思例子可以让你得到:
1.班级中的所有属性
2.单个属性,前提是您知道字符串名称
有没有办法(使用反射,TypeDescriptor或其他方法)在运行时获取类中属性的字符串名称,前提是我拥有的是类和属性的实例?
编辑 我知道我可以使用反射轻松获取类中的所有属性,然后获取每个属性的名称.我要求的是一个函数来给我一个属性的名称,前提是我传递了属性的实例.换句话说,如何从class.GetType().GetProperty(myProperty)中找到PropertyInfo []数组返回给我的属性,以便从中获取PropertyInfo.Name?
我遇到了一个我没想到的问题.一个例子可能比一段更好地说明我的问题:
更新:跳转到最后一个代码块,以获得更有说服力的代码示例.
public class A
{
public string B { get; set; }
}
public class C : A { }
Run Code Online (Sandbox Code Playgroud)
以下是方法中的一些代码:
var a = typeof(C).GetMember("B")[0];
var b = typeof(A).GetMember("B")[0];
Expression<Func<C, string>> c = x => x.B;
var d = (c.Body as MemberExpression).Member;
Run Code Online (Sandbox Code Playgroud)
以下是一些比较的结果:
a == b //false
a == d //false
b == d //true
Run Code Online (Sandbox Code Playgroud)
前两个有些出乎意料.我知道即使B不是虚拟的,C也可以用w new运算符定义一个具有相同名称的属性,但在这种情况下我没有.
第二个对我来说真是最让人惊讶的(也是我问题的核心).即使lambda的参数明确定义为C类,它仍然返回它,就像从基类访问属性一样.
我正在寻找的是一种从lambda表达式获取MemberInfo的方法,就好像我已经使用参数类型的反射来获取MemberInfo.我的项目本质上将MemberInfos存储在各种字典中,它需要具有可以通过提供lambda表达式来访问元素的功能.
重复的代码示例由Danny Chen提供
public class Base
{
public string Name { get; set; }
}
public class Derived : Base …Run Code Online (Sandbox Code Playgroud) 我想在不使用魔术字符串的情况下将属性名称传递给函数.
就像是:
Get<ObjectType>(x=>x.Property1);
Run Code Online (Sandbox Code Playgroud)
其中Property1是ObjectType类型的属性.
方法实现会是什么样的?
这是一个我无法回答的粗略问题.
主程序
class Program{
static void Main(string[] args){
Console.WriteLine("Begin");
var myClass = new MyClass();
Util.Print(myClass.Id);
Util.Print(myClass.Server);
Util.Print(myClass.Ping);
Console.WriteLine("End");
}
}
Run Code Online (Sandbox Code Playgroud)
如何实现Util.Print方法以将此输出提供给控制台:
Begin
Id
Server
Ping
End
Run Code Online (Sandbox Code Playgroud) 如何使用Type.GetMethod()来获取具有lambda参数的方法?我正在尝试使用以下方法获取类似Func的参数的Queryable.Any方法:
typeof(Queryable).GetMethod("Any", new Type[]{typeof(Func<ObjType, bool>)})
Run Code Online (Sandbox Code Playgroud)
但它一直返回null.