问答 - 如何以强类型方式获取 属性/函数/操作/方法(接口或 Class)的名称?
Q&A - How to get the name of Property / Function / Action / Method (of an Interface or Class), in a strongly type way?
问题描述
假设您有一个接口/class,并希望获得一个 Property/Func/Action 名称,最佳做法是什么?
例如给定:
public interface IConvertible
{
// ...
bool ToBoolean(IFormatProvider provider);
// ...
}
如何以强类型方式获取 'ToBoolean' 方法的名称?
此外,如何从
获取 IsValueCreated 的 属性 名称
Lazy<object>.IsValueCreated
动机
当您对接口 [方法/属性 / 等] 进行反射时,编译器将帮助您找到对它的所有引用。
对于 .Net 5 及更高版本:
使用 nameof (credits to 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;
}
}
}
资源
- Using obect's property names in strongly type way
- C# Strongly Typed Attribute member to describe property
- Get the name(s) of interface methods strong typed
等待您的输入/建议/见解...
问题描述
假设您有一个接口/class,并希望获得一个 Property/Func/Action 名称,最佳做法是什么?
例如给定:
public interface IConvertible
{
// ...
bool ToBoolean(IFormatProvider provider);
// ...
}
如何以强类型方式获取 'ToBoolean' 方法的名称?
此外,如何从
获取 IsValueCreated 的 属性 名称Lazy<object>.IsValueCreated
动机
当您对接口 [方法/属性 / 等] 进行反射时,编译器将帮助您找到对它的所有引用。
对于 .Net 5 及更高版本: 使用 nameof (credits to 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;
}
}
}
资源
- Using obect's property names in strongly type way
- C# Strongly Typed Attribute member to describe property
- Get the name(s) of interface methods strong typed
等待您的输入/建议/见解...