如何获得Generic Property的名称?

William Liu 326 Reputation points
2021-09-03T01:11:58.11+00:00

是否可以利用 nameof 获得generic property的名称? 如果不能是否有其它方法可以获得? 详见下面的测试对比代码.

    ////////////// generic  /////////////////////////////////

    [Fact]
    public void GetPropertyName_FromGeneric()
    {
        // un-compilable

        // Console.WriteLine(nameof(Foo<T>.Value));
        // Console.WriteLine(nameof(Foo<>.Value));
    }

    private class Foo<T>
    {
        public T? Value { get; set; }
    }

    ////////////// no-generic  /////////////////////////////////

    [Fact]
    public void GetPropertyName_FromNonGeneric()
    {
        Console.WriteLine(nameof(Bar.Value));
    }

    private class Bar
    {
        public int Value { get; set; }
    }

可以看到,对于generic类Foo, 我还没有找到可用的 nameof 方法来获得属性"Value"的名称. 请帮忙指出可用的方法,谢谢!

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,641 questions
{count} votes

Accepted answer
  1. stone z 76 Reputation points
    2021-09-03T03:21:03.657+00:00
                Foo<int> foo = new Foo<int>();
                string name= nameof(foo.Value);
                Console.WriteLine(name);
    

3 additional answers

Sort by: Most helpful
  1. Timon Yang-MSFT 9,586 Reputation points
    2021-09-03T05:53:37.36+00:00

    How about using reflection?

        class Program  
        {  
            static void Main(string[] args)  
            {  
                Type type = typeof(MyClass<>);  
                  
                PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);  
                  
                var propertiesNames = propertyInfos.Select(prop => prop.Name);  
      
                foreach (var item in propertiesNames)  
                {  
                    Console.WriteLine(item);  
                }  
                Console.ReadLine();  
            }  
        }  
        class MyClass<T>  
        {  
            public T Value { get; set; }  
        }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. AgaveJoe 27,686 Reputation points
    2021-09-03T13:55:58.737+00:00

    How about a Generic method. Reflection is required to find the property names at runtime.

    public static void WritePropertyNameAndValues<T>(T obj)
    {
        foreach (var prop in obj.GetType().GetProperties())
        {
            Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(obj, null));
        }
    }
    

  3. Karen Payne MVP 35,386 Reputation points
    2021-09-04T01:42:17.337+00:00

    There really is not cool way.

    using System.Diagnostics;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace BaseCoreUnitTestProject
    {
        [TestClass]
        public partial class MainTest 
        {
            [TestMethod]
            public void TestMethod1()
            {
                Debug.WriteLine($"{nameof(Foo<object>.Value)}");
    
                var foo = new Foo<int> {Value = 99};
                foo.Ask();
    
                var foo1 = new Foo<object> {Value = true};
                foo1.Ask();
            }
        }
        class Foo<T>
        {
            public T? Value { get; set; }
    
            public void Ask()
            {
                Debug.WriteLine($"From Ask: {nameof(Value)}");
            }
        }
    }