(参见下面我使用我接受的答案创建的解决方案)
我正在尝试提高一些涉及反射的代码的可维护性.该应用程序有一个.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) 在C#6中,您可以使用nameof()运算符来获取包含变量名称或类型的字符串.
这是在编译时评估,还是在运行时通过一些Roslyn API评估?
可能重复:
查找传递给C#中函数的变量名称
我想获取变量或参数的名称:
例如,如果我有:
var myInput = "input";
var nameOfVar = GETNAME(myInput); // ==> nameOfVar should be = myInput
void testName([Type?] myInput)
{
var nameOfParam = GETNAME(myInput); // ==> nameOfParam should be = myInput
}
Run Code Online (Sandbox Code Playgroud)
我怎么能在C#中做到这一点?
我需要能够控制如何/是否序列化类上的某些属性.最简单的情况是[ScriptIgnore].但是,我只希望这些属性能够适用于我正在处理的这个特定的序列化情况 - 如果应用程序中的下游其他模块也想要序列化这些对象,则这些属性都不应该妨碍.
所以我的想法是在属性MyAttribute上使用自定义属性,并使用知道查找该属性的钩子初始化JsonSerializer的特定实例.
乍一看,我没有看到JSON.NET中任何可用的钩子点都会为PropertyInfo当前属性提供这样的检查 - 只有属性的值.我错过了什么吗?或者更好的方法来解决这个问题?
我使用了一些强类型表达式,这些表达式被序列化以允许我的UI代码具有强类型排序和搜索表达式.这些是类型的Expression<Func<TModel,TProperty>>并且如此使用:SortOption.Field = (p => p.FirstName);.对于这个简单的案例,我已经完美地完成了这项工作.
我用来解析"FirstName"属性的代码实际上重用了我们使用的第三方产品中的一些现有功能,并且它工作得很好,直到我们开始使用深层嵌套的属性(SortOption.Field = (p => p.Address.State.Abbreviation);).此代码在支持深层嵌套属性的需求方面有一些非常不同的假设.
至于这段代码的作用,我并不是真的理解它而不是改变代码,我想我应该从头开始编写这个功能.但是,我不知道这样做的好方法.我怀疑我们可以做一些比做ToString()和执行字符串解析更好的事情.那么有什么好办法来处理琐碎和深层嵌套的案例呢?
要求:
p => p.FirstName我需要一串"FirstName".p => p.Address.State.Abbreviation我需要一串"Address.State.Abbreviation"虽然对我的问题的答案并不重要,但我怀疑我的序列化/反序列化代码对将来发现这个问题的其他人有用,所以它在下面.同样,这段代码对这个问题并不重要 - 我只是觉得它可能对某些人有所帮助.请注意,DynamicExpression.ParseLambda它来自动态LINQ的东西,Property.PropertyToString()这是这个问题的关键.
/// <summary>
/// This defines a framework to pass, across serialized tiers, sorting logic to be performed.
/// </summary>
/// <typeparam name="TModel">This is the object type that you are filtering.</typeparam>
/// <typeparam name="TProperty">This is the property on the …Run Code Online (Sandbox Code Playgroud) 我有一个表达式指向我的类型的属性.但它并不适用于每种房产类型."不代表"意味着它会导致不同的表达类型.我认为它会导致a
MemberExpression但事实并非如此.
对于int和Guid它导致一个UnaryExpression和string
在MemberExpression.
我有点困惑 ;)
我的课
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
测试代码
Person p = new Person { Age = 16, Name = "John" };
Expression<Func<Person, object>> expression1 = x => x.Age;
// expression1.Body = UnaryExpression;
Expression<Func<Person, object>> expression2 = x => x.Name;
// expression2.Body = MemberExpression;
Run Code Online (Sandbox Code Playgroud)
我如何比较两个表达式并检查它们是否意味着相同的类型和相同的属性?
感谢用户dasblinkenlight带我走上正轨. …
我正在尝试编写一个函数,它将使用如下语法提取属性的名称和类型:
private class SomeClass
{
Public string Col1;
}
PropertyMapper<Somewhere> propertyMapper = new PropertyMapper<Somewhere>();
propertyMapper.MapProperty(x => x.Col1)
Run Code Online (Sandbox Code Playgroud)
有没有办法将属性传递给函数而不对此语法进行任何重大更改?
我想获取属性名称和属性类型.
所以在下面的例子中我想要检索
Name = "Col1" 和 Type = "System.String"
有人可以帮忙吗?
我遇到了一个我没想到的问题.一个例子可能比一段更好地说明我的问题:
更新:跳转到最后一个代码块,以获得更有说服力的代码示例.
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) 无论如何我可以获得类属性的名称IntProperty吗?
public class ClassName
{
public static int IntProperty { get { return 0; } }
}
//something like below but I want to get the string of "IntProperty"
ClassName.IntProperty.GetType().Name
Run Code Online (Sandbox Code Playgroud)
基本上我想要做的是动态地将属性名称字符串保存到数据库中,稍后从数据库中检索它并动态调用属性.
好像我正在寻找的东西类似于我认为的鸭子打字.
谢谢!
更新:
这是实际的代码.这更像是一种工作流程.但是每个任务都被定义为类的属性(类用于对任务进行分组).
public class ApplicationTask
{
public static Task<string> SendIncompleteNotification
{
get
{
return new Task<string>
(
a => Console.WriteLine("Sample Task")
, "This is a sample task which does nothing."
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,代码将能够检索类和属性的全名,如下所示:namespace.ApplicationTask.SendIncompleteNotification并将其保存到数据库中.稍后,代码将读取字符串并动态创建任务并将其传递给另一个任务以执行.
我正在使用ASP.NET MVC 2 Preview 2并编写了一个自定义的HtmlHelper扩展方法来使用表达式创建标签.TModel来自具有属性的简单类,属性可以具有定义验证要求的属性.我试图找出表达式在我的label方法中表示的属性上是否存在某个属性.
类和标签的代码是:
public class MyViewModel
{
[Required]
public string MyProperty { get; set; }
}
public static MvcHtmlString Label<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string label)
{
return MvcHtmlString.Create(string.Concat("<label for=\"", expression.GetInputName(), "\">", label, "</label>"));
}
public static string GetInputName<TModel, TProperty>(this Expression<Func<TModel, TProperty>> expression)
{
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
}
Run Code Online (Sandbox Code Playgroud)
然后我会像这样称呼标签:
Html.Label(x => x.MyProperty, "My Label")
Run Code Online (Sandbox Code Playgroud)
有没有办法找出传递给Label方法的表达式值中的属性是否具有Required属性?
我发现如果它存在,执行以下操作确实可以获得属性,但我希望有更简洁的方法来实现这一点.
public static MvcHtmlString Label<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string label)
{
System.Attribute.GetCustomAttribute(Expression.Property(Expression.Parameter(expression.Parameters[0].Type, expression.GetInputName()), expression.GetInputName()).Member, typeof(RequiredAttribute))
return …Run Code Online (Sandbox Code Playgroud) c# ×10
lambda ×5
reflection ×3
properties ×2
.net ×1
attributes ×1
c#-6.0 ×1
expression ×1
gettype ×1
json.net ×1
roslyn ×1