通过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) 让我用下面的例子来解释我的问题:
public string ExampleFunction(string Variable) {
return something;
}
string WhatIsMyName = "Hello World"';
string Hello = ExampleFunction(WhatIsMyName);
Run Code Online (Sandbox Code Playgroud)
当我将变量"WhatIsMyName"传递给示例函数时,我希望能够获取原始变量名称的字符串.也许是这样的:
Variable.OriginalName.ToString()
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
可能重复:
查找传递给C#中函数的变量名称
下面的课程包含现场城市.
我需要动态确定字段名称,因为它是在类声明中输入的,即我需要从对象城市的实例中获取字符串"city".
我试图通过检查其在DoSomething()中的类型来做到这一点,但在检查调试器中的Type的内容时找不到它.
可能吗?
public class Person
{
public string city = "New York";
public Person()
{
}
public void DoSomething()
{
Type t = city.GetType();
string field_name = t.SomeUnkownFunction();
//would return the string "city" if it existed!
}
}
Run Code Online (Sandbox Code Playgroud)
下面他们的答案中的一些人问我为什么要这样做.这就是原因.
在我的真实世界中,城市上方有一个自定义属性.
[MyCustomAttribute("param1", "param2", etc)]
public string city = "New York";
Run Code Online (Sandbox Code Playgroud)
我需要在其他代码中使用此属性.要获取属性,我使用反射.在反射代码中我需要输入字符串"city"
MyCustomAttribute attr;
Type t = typeof(Person);
foreach (FieldInfo field in t.GetFields())
{
if (field.Name == "city")
{
//do stuff when we find the field that has …Run Code Online (Sandbox Code Playgroud) 我有兴趣以重构安全的方式在运行时检索局部变量(和参数)的名称.我有以下扩展方法:
public static string GetVariableName<T>(Expression<Func<T>> variableAccessExpression)
{
var memberExpression = variableAccessExpression.Body as MemberExpression;
return memberExpression.Member.Name;
}
Run Code Online (Sandbox Code Playgroud)
...返回通过lambda表达式捕获的变量的名称:
static void Main(string[] args)
{
Console.WriteLine(GetVariableName(() => args));
// Output: "args"
int num = 0;
Console.WriteLine(GetVariableName(() => num));
// Output: "num"
}
Run Code Online (Sandbox Code Playgroud)
但是,这只能起作用,因为C#编译器将在匿名函数中捕获的任何局部变量(和参数)提升为幕后编译器生成的类中的同名实例变量(每个Jon Skeet).如果不是这种情况,则转换为Bodyto MemberExpression会失败,因为MemberExpression代表字段或属性访问.
这个变量是促销记录的行为,还是一个实现细节可能会在框架的其他版本中发生变化?
注意:这个问题是我前一个关于参数验证的概括.
如果我有这样的代码:
public class Program
{
public static void Main()
{
string bar = "";
int foo = 24;
}
}
Run Code Online (Sandbox Code Playgroud)
我可以Main使用以下方法获取声明的局部变量:
var flag = BindingFlags.Static | BindingFlags.Public;
var fields = typeof(Program).GetMethod("Main", flags).GetMethodBody().LocalVariables;
Run Code Online (Sandbox Code Playgroud)
这将返回一个IList<LocalVariableInfo>与LocalVariableInfo只有三个属性:IsPinned,LocalIndex和LocalType.所以没有Name财产存在.
我想知道的是你可以看到生成的变量名称IL code:
.method public hidebysig static void Main() cil managed
{
.entrypoint
// Code size 11 (0xb)
.maxstack 1
.locals init ([0] string bar,
[1] int32 foo)
IL_0000: nop
IL_0001: ldstr …Run Code Online (Sandbox Code Playgroud) 可能重复:
获取变量或参数的名称
我希望能够将变量的名称作为字符串.
这可以通过使用无参数的lambda表达式有效地实现.但是,这会产生性能开销,并且它不是内置功能.
.NET 4.5 CallerMemberNameAttribute提供了一个调用者的名称作为方法参数.这为我们提供了内置和更好(在某些情况下)的方式来满足特定情况.
.NET 4.5为特定上下文提供了该领域的改进.现在还有一个更好的^意味着将任何变量的名称作为字符串?
根据要求,这是我想要实现的一般用法示例:
//Assume 'myVariable' is a local variable, member variable, static member variable, constant, parameter or even a property.
string myVariableName = ...; //This should get the string name of myVariable
Run Code Online (Sandbox Code Playgroud)
^更好,我的意思是更快,不需要反射,内置.NET或更优雅,但最好是这些的组合.
我有课
public class MyCoolProp
{
public string FullName {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在另一个类中,我将此作为属性:
public class MyMainClass
{
public MyCoolProp coolprop {get;set;}
public void DoSomething()
{
MessageBox.Show(nameof(coolprop.FullName));
}
}
Run Code Online (Sandbox Code Playgroud)
实际结果是:“全名”
但我想要这样的组合:“coolprop.FullName”
我不想做这样的事情:
nameof(coolprop) + "." + nameof(coolprop.FullName);
Run Code Online (Sandbox Code Playgroud)
也许可以在扩展中实现?
如果我将属性重命名为“coolprop”,输出也应该具有新名称
我希望能够使用强类型语法检索类型属性的名称.我已经有一个函数来获取实例的属性名称:
public static string PropertyName<T, TReturn>(this T obj, Expression<Func<T, TReturn>> property) where T : class
{
MemberExpression body = (MemberExpression) property.Body;
if (body == null) throw new ArgumentException("The provided expression did not point to a property.");
return body.Member.Name;
}
Run Code Online (Sandbox Code Playgroud)
可以这样调用:
Car car = new Car();
car.PropertyName(x => x.Wheels) //returns "Wheels"
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建另一个可以支持以下功能:
Type t = Typeof(Car);
t.PropertyName(x => x.Wheels) //should return "Wheels"
Run Code Online (Sandbox Code Playgroud)
或者只是(甚至更好!):
Car.PropertyName(x => x.Wheels)
Run Code Online (Sandbox Code Playgroud)
我该怎么做?
我有一个枚举如下:
public enum MyEnumeration
{
myFirstValue = 0,
mySecondValue = 1
}
Run Code Online (Sandbox Code Playgroud)
问题,我希望我的枚举类型为字符串,例如:
var str = MyEnumeration.ToString();
/// str = "MyEnumeration"
Run Code Online (Sandbox Code Playgroud)
(仅供参考,以上不起作用)
我可以在网上找到大量的答案来获取'myFirstValue'和'mySecondValue'的字符串值,但不是Enumeration.
谢谢你的帮助!
(忍者编辑)感谢大家花时间回答.我不相信这是标记问题的重复.这是针对枚举的直接问题,重复问题中未提供此解决方案