如何通过反射获取当前属性名称?(How to get current property name v

2019-06-17 19:45发布

我想获得属性的名称,当我通过反射机制,它是。 可能吗?

更新:我有这样的代码:

    public CarType Car
    {
        get { return (Wheel) this["Wheel"];}
        set { this["Wheel"] = value; }
    }

而且因为我需要更多这样的性质,我想这样做:

    public CarType Car
    {
        get { return (Wheel) this[GetThisPropertyName()];}
        set { this[GetThisPropertyName()] = value; }
    }

Answer 1:

由于属性是真的只是方法可以做到这一点,清理返回的get_:

class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            var x = p.Something;
            Console.ReadLine();
        }

        public string Something
        {
            get
            {
                return MethodBase.GetCurrentMethod().Name;
            }
        }
    }

如果配置文件中的表现,你应该找到MethodBase.GetCurrentMethod()是比哩更快的StackFrame。 在.NET 1.1中,也会发生问题的StackFrame在释放模式(从内存中,我想我发现这是快3倍)。

这就是说我相信性能问题不会造成problem-的太多,但上的StackFrame缓慢一个有趣的讨论,可以在这里找到 。

我想另一个选择,如果你担心性能会创建一个Visual Studio的智能感知代码段为您创建的财产,还创建了对应属性名的字符串。



Answer 2:

我想更多地了解你需要它,因为在我看来,你应该已经知道您正在使用的属性访问器的工作是什么性质的上下文。 如果必须,但是,你很可能使用MethodBase.GetCurrentMethod() ,请将.Name和删除后任何get_/set_

更新

根据您的修改,我会说,你应该使用继承,而不是反射。 我不知道是你的字典里什么样的数据,但在我看来,你真的希望有不同的汽车类,说轿车,跑车,越野车,旅行车,不守型的局部变量。 然后,你将有对于该类型的汽车不是合适的方法实现。 相反,找出你,然后做什么样的车的东西,然后你只需调用适当的方法和Car对象不基于它是什么类型的正确的事情。

 public interface ICar
 {
      void Drive( decimal velocity, Orientation orientation );
      void Shift( int gear );
      ...
 }

 public abstract class Car : ICar
 {
      public virtual void Drive( decimal velocity, Orientation orientation )
      {
          ...some default implementation...
      }

      public abstract void Shift( int gear );

      ...
 }

 public class AutomaticTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }

 public class ManualTransmission : Car
 {
       public override void Shift( int gear )
       {
          ...some specific implementation...
       }
 }


Answer 3:

使用MethodBase.GetCurrentMethod(),而不是!

反思是用来做工作,不能在编译时完成的类型。 获取属性访问你在的名字可以在编译时决定,所以你可能不应该使用反射它。

你从使用调用堆栈使用的访问方法的名称System.Diagnostics.StackTrace虽然。

    string GetPropertyName()
    {
        StackTrace callStackTrace = new StackTrace();
        StackFrame propertyFrame = callStackTrace.GetFrame(1); // 1: below GetPropertyName frame
        string properyAccessorName = propertyFrame.GetMethod().Name;

        return properyAccessorName.Replace("get_","").Replace("set_","");
    }


Answer 4:

略显混乱比如你呈现,除非我只是不明白这一点。 从C#6.0,你可以使用nameof操作。

public CarType MyProperty
{
    get { return (CarType)this[nameof(MyProperty)]};
    set { this[nameof(MyProperty)] = value]};
}

如果您有反正处理您的getter / setter方法,你可以使用C#4.5 CallerMemberName属性,在这种情况下,你甚至不需要重复的名字。

public CarType MyProperty
{
    get { return Get<CarType>(); }
    set { Set(value); }
}

public T Get<T>([CallerMemberName]string name = null)
{
    return (T)this[name];
}   

public void Set<T>(T value, [CallerMemberName]string name = null)
{
    this[name] = value;
}  


Answer 5:

FWIW我实现了一个系统是这样的:

    [CrmAttribute("firstname")]
    public string FirstName
    {
       get { return GetPropValue<string>(MethodBase.GetCurrentMethod().Name); }
       set { SetPropValue(MethodBase.GetCurrentMethod().Name, value); }
    }

    // this is in a base class, skipped that bit for clairty
    public T GetPropValue<T>(string propName)
    {
        propName = propName.Replace("get_", "").Replace("set_", "");
        string attributeName = GetCrmAttributeName(propName);
        return GetAttributeValue<T>(attributeName);            
    }

    public void SetPropValue(string propName, object value)
    {
        propName = propName.Replace("get_", "").Replace("set_", "");
        string attributeName = GetCrmAttributeName(propName);
        SetAttributeValue(attributeName, value);
    }

    private static Dictionary<string, string> PropToAttributeMap = new Dictionary<string, string>();
    private string GetCrmAttributeName(string propertyName)
    {
         // keyName for our propertyName to (static) CrmAttributeName cache
         string keyName = this.GetType().Name + propertyName;
         // have we already done this mapping?
         if (!PropToAttributeMap.ContainsKey(keyName))
         {
             Type t = this.GetType();
             PropertyInfo info = t.GetProperty(propertyName);
             if (info == null)
             {
                 throw new Exception("Cannot find a propety called " + propertyName);
             }

             object[] attrs = info.GetCustomAttributes(false);
             foreach (object o in attrs)
             {
                 CrmAttributeAttribute attr = o as CrmAttributeAttribute ;
                 if (attr != null)
                 {
                     // found it. Save the mapping for next time.
                     PropToAttributeMap[keyName] = attr.AttributeName;
                     return attr.AttributeName;
                 }
              }
              throw new Exception("Missing MemberOf attribute for " + info.Name + "." + propertyName + ". Could not auto-access value");
           }

           // return the existing mapping
           string result = PropToAttributeMap[keyName];
           return result;
        }

还有一个叫CrmAttributeAttribute自定义属性类。

我强烈建议不要使用GetStackFrame()作为解决方案的一部分,我原来的解决方案版本是最初的更加简洁:

return GetPropValue<string>();

但它是比上面的版本慢600X。



Answer 6:

是的!

string test = "test string";
Type type = test.GetType();

PropertyInfo[] propInfos = type.GetProperties();
for (int i = 0; i < propInfos.Length; i++) 
{
    PropertyInfo pi = (PropertyInfo)propInfos.GetValue(i);
    string propName = pi.Name;
}


Answer 7:

尝试使用System.Diagnostics.StackTrace反映在调用堆栈。 该属性应该是在某个地方调用堆栈(可能在顶部,如果你直接从酒店的代码中调用它)。



Answer 8:

路#1

var a = nameof(SampleMethod);    //a == SampleMethod
var b = nameof(SampleVariable);  //b == SampleVariable
var c = nameof(SampleProperty);  //c == SampleProperty

路#2

MethodBase.GetCurrentMethod().Name; // Name of method in which you call the code
MethodBase.GetCurrentMethod().Name.Replace("set_", "").Replace("get_", ""); // current Property

路#3

从堆栈跟踪:

public static class Props
{
    public static string CurrPropName => 
         (new StackTrace()).GetFrame(1).GetMethod().Name.Replace("set_", "").Replace("get_", "");

    public static string CurrMethodName => 
        (new StackTrace()).GetFrame(1).GetMethod().Name;
}

你只需要调用Props.CurrPropNameProps.CurrMethodName


办法#4

解决方案.NET 4.5+:

public static class Props
{
    public static string GetCallerName([System.Runtime.CompilerServices.CallerMemberName] String propertyName = "")
    {
         return propertyName;
    }
}

usgae: Props.GetCallerName();



文章来源: How to get current property name via reflection?