【问题标题】:Q&A - How to get the name of Property / Function / Action / Method (of an Interface or Class), in a strongly type way?问答 - 如何以强类型方式获取属性/函数/动作/方法(接口或类)的名称?
【发布时间】:2015-11-25 11:02:00
【问题描述】:

问题描述

假设您有一个接口/类,并希望获得一个 Property/Func/Action 名称,那么如何以及最好的做法是什么?

例如给定:

public interface IConvertible
{    
    // ...
    bool ToBoolean(IFormatProvider provider);
    // ...
}

如何以强类型的方式获取“ToBoolean”方法的名称?

还有,如何

获取IsValueCreated的属性名
Lazy<object>.IsValueCreated

动机

当您对接口 [方法/属性/等] 进行反射时,编译器将帮助您找到对它的所有引用。

【问题讨论】:

  • 取什么名字?方法名称?
  • 您使用的是哪个 C# 版本?
  • 使用 .Net 4.5v,获取 'ToBoolean' 名称..

标签: c# reflection interface proxy strong-typing


【解决方案1】:

对于 .Net 5 及更高版本: 使用nameof(归功于m-kazem-akhgary

.Net 4.5v 及以下:

using System;
using System.Linq.Expressions;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using LazyHelper = DotNetSandbox.InterfaceNames<System.Lazy<object>>;

namespace DotNetSandbox
{
    // Use case / Example:
    [TestClass]
    public class InterfaceNamesTests
    {
        [TestMethod]
        public void InterfaceNamesTest()
        {
            // Option 1 - Not strongly typed
            string nameA = typeof(IConvertible).GetMethod("ToBoolean").Name;
            Console.WriteLine(nameA);    // OUTPUT: ToBoolean
            string nameB = typeof(Lazy<object>).GetProperty("IsValueCreated").Name;
            Console.WriteLine(nameB);    // OUTPUT: ToBoolean

            // *** Option 2 ***************
            Console.WriteLine();
            Console.WriteLine("Option 2 - Strongly typed way:");
            IConvertible @interface = InterfaceNames<IConvertible>.Create();

            Func<IFormatProvider, bool> func = @interface.ToBoolean;
            string name1 = func.Method.Name;
            Console.WriteLine(name1);   // OUTPUT: ToBoolean

            string propName = InterfaceNames<Lazy<object>>.GetPropertyName(i => i.IsValueCreated);
            Console.WriteLine(propName);   // OUTPUT: IsValueCreated
            //OR (For short version - declare alias using, see using region..)
            string propName2 = LazyHelper.GetPropertyName(i => i.IsValueCreated);
            Console.WriteLine(propName2);   // OUTPUT: IsValueCreated


            // Other options results with complex/unclear code.
        }
    }

    // Helper class
    public class InterfaceNames<T> : RealProxy
    {
        private InterfaceNames() : base(typeof(T)) { }

        public static T Create()
        {
            return (T)new InterfaceNames<T>().GetTransparentProxy();
        }

        public override IMessage Invoke(IMessage msg)
        {
            return null;
        }

        public static string GetName(Delegate d)
        {
            return d.Method.Name;
        }

        public static string GetPropertyName<TProp>(Expression<Func<T, TProp>> prop)
        {
            // Credits to p-s-w-g
            var body = prop.Body as MemberExpression;
            return body == null ? null : body.Member.Name;
        }
    }
}

资源

等待您的意见/建议/见解...

【讨论】:

  • 尊敬的,您能否详细说明为什么这不是答案?
  • 我首先没有理解您的问题。好的,所以这是一个自我回答的问题。获取名称的另一种方法是关键字 nameof。例如:nameof(ToBoolean)
  • 很好,不知道 'nameof',但它仍然是新的,在 .Net 4.5v 及更低版本中不受支持..
  • nameof 不是框架功能,它是 C# 编译器功能
猜你喜欢
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多