获取代理内通用方法的名称 class
Get name of generic method inside a proxy class
我想创建一个代理 class,它将能够检索参数中给定的方法的名称,以及具有通用完成功能的参数实例(也就是我不想要 nameof( ) 或魔法字符串)。
例如,我希望能够做类似
的事情
public interface ITestInterface
{
void TestMethod(Param myParam)
}
var proxy = new Proxy<ITestInterface>();
var param = new Param();
proxy.WriteName(x => ITestInterface.TestMethod(param));
和代理 class 能够检索方法的名称并对参数的实例执行 tostring :
public class Proxy<T>
{
public void WriteName(Something something)
{
Console.WriteLine(something.MethodName); // write "TestMethod"
Console.WriteLine(something.Parameter.ToString()); // use the tostring of the instance object
}
}
感谢您的帮助
如果我没理解错你可以试试这个:
public class Proxy<T>
{
public void WriteName(Expression<Action> action)
{
var methodCallExp = (MethodCallExpression)action.Body;
Console.WriteLine(methodCallExp.Arguments.First().ToString());
Console.WriteLine(methodCallExp.Method.Name);
}
}
并像这样调用代理 class:
var proxy = new Proxy<ITestInterface>();
proxy.WriteName(() => new ConcreteTestInterface().TestMethod(param));
我想说要支持所有可能的场景并不容易,但是对于你在问题中描述的内容,你可以尝试使用 expression trees:
public class Proxy<T>
{
public void WriteName(Expression<Action<T>> something)
{
// TODO: add correct handling for not supported operations
if (something.Body is MethodCallExpression mc)
{
Console.WriteLine(mc.Method.Name);
foreach (var arg in mc.Arguments)
{
if (arg is MemberExpression me && me.Expression is ConstantExpression cnst)
{
var val = me.Member.MemberType switch
{
MemberTypes.Field => ((FieldInfo)me.Member).GetValue(cnst.Value),
MemberTypes.Property => ((PropertyInfo)me.Member).GetValue(cnst.Value),
_ => null
};
Console.WriteLine(val);
}
}
}
}
}
和用法:
var proxy = new Proxy<ITestInterface>();
var param = new Param();
proxy.WriteName(t => t.TestMethod(param)); // actually many more can be passed here
我想创建一个代理 class,它将能够检索参数中给定的方法的名称,以及具有通用完成功能的参数实例(也就是我不想要 nameof( ) 或魔法字符串)。
例如,我希望能够做类似
的事情public interface ITestInterface
{
void TestMethod(Param myParam)
}
var proxy = new Proxy<ITestInterface>();
var param = new Param();
proxy.WriteName(x => ITestInterface.TestMethod(param));
和代理 class 能够检索方法的名称并对参数的实例执行 tostring :
public class Proxy<T>
{
public void WriteName(Something something)
{
Console.WriteLine(something.MethodName); // write "TestMethod"
Console.WriteLine(something.Parameter.ToString()); // use the tostring of the instance object
}
}
感谢您的帮助
如果我没理解错你可以试试这个:
public class Proxy<T>
{
public void WriteName(Expression<Action> action)
{
var methodCallExp = (MethodCallExpression)action.Body;
Console.WriteLine(methodCallExp.Arguments.First().ToString());
Console.WriteLine(methodCallExp.Method.Name);
}
}
并像这样调用代理 class:
var proxy = new Proxy<ITestInterface>();
proxy.WriteName(() => new ConcreteTestInterface().TestMethod(param));
我想说要支持所有可能的场景并不容易,但是对于你在问题中描述的内容,你可以尝试使用 expression trees:
public class Proxy<T>
{
public void WriteName(Expression<Action<T>> something)
{
// TODO: add correct handling for not supported operations
if (something.Body is MethodCallExpression mc)
{
Console.WriteLine(mc.Method.Name);
foreach (var arg in mc.Arguments)
{
if (arg is MemberExpression me && me.Expression is ConstantExpression cnst)
{
var val = me.Member.MemberType switch
{
MemberTypes.Field => ((FieldInfo)me.Member).GetValue(cnst.Value),
MemberTypes.Property => ((PropertyInfo)me.Member).GetValue(cnst.Value),
_ => null
};
Console.WriteLine(val);
}
}
}
}
}
和用法:
var proxy = new Proxy<ITestInterface>();
var param = new Param();
proxy.WriteName(t => t.TestMethod(param)); // actually many more can be passed here