Problem description
Assuming you have an interface / class, and wish to get a Property/Func/Action name, how and what is the best practice to do so?
e.g. given:
public interface IConvertible
{
// ...
bool ToBoolean(IFormatProvider provider);
// ...
}
How to get the name of 'ToBoolean' method, in a strongly-typed way?
Also, how to get the property name of IsValueCreated from
Lazy<object>.IsValueCreated
Motivation
When you'll do reflection on an interface [method / property / etc], the compiler will help you find all references to it.
For .Net 5 and above:
use nameof (credits to m-kazem-akhgary)
For .Net 4.5v and below:
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;
}
}
}
Resources
- 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
Waiting for your input / suggestions / insights...