将方法传递到需要方法名称的另一个方法
下面是一些用于传递对包含字符串作为参数的方法的引用的代码,此问题的目的是围绕使用泛型否定需要定义实际的类型!将方法传递到需要方法名称的另一个方法
Impossible<ExampleSource, string>.Example(c => c.NonString); //does not work
Impossible<ExampleSource, string>.Example<int>(c => c.NonString); //does work
这里的想法是让第一个“非字符串”呼叫工作,而不必定义参数类型或声明不可能在一个新的函数,它Func键< INT,TResult >。
public static void Example(Expression<Func<TSource, Func<int, TResult>>> function)
{ Process(function as MethodCallExpression); } //invalid solution...
在Java中,这可能使用Func键<?来实现,TResult >
public class Impossible<TSource, TResult>
{
public static void Example(Expression<Func<TSource, Func<TResult>>> function)
{ Process(function as MethodCallExpression); }
public static void Example(Expression<Func<TSource, Func<string, TResult>>> function)
{ Process(function as MethodCallExpression); }
public static void Example(Expression<Func<TSource, Func<string, string, TResult>>> function)
{ Process(function as MethodCallExpression); }
public static void Example<T1>(Expression<Func<TSource, Func<T1, TResult>>> function)
{ Process(function as MethodCallExpression); }
public static void Example<T1, T2>(Expression<Func<TSource, Func<T1, T2, TResult>>> function)
{ Process(function as MethodCallExpression); }
private static void Process(MethodCallExpression exp)
{
if (exp == null) return;
Console.WriteLine(exp.Method.Name);
}
}
public class ExampleSource
{
public string NoParams() { return ""; }
public string OneParam(string one) { return ""; }
public string TwoParams(string one, string two) { return ""; }
public string NonString(int i) { return ""; }
}
public class Consumer
{
public void Argh()
{
Impossible<ExampleSource, string>.Example(c => c.NoParams);
Impossible<ExampleSource, string>.Example(c => c.OneParam);
Impossible<ExampleSource, string>.Example(c => c.TwoParams);
Impossible<ExampleSource, string>.Example<int>(c => c.NonString);
Impossible<ExampleSource, string>.Example(c => c.NonString); //MAKE THIS WORK
}
}
最明确,最强的打字我能想出这个职位的问题部分上市:
Why is there not a fieldof
or methodof
operator in C#?
要顶到,我需要更多地了解你的目标是什么(这里有更大的图片)。
这里的最终目标是通过查找基于类型的路由来传递ASP.NET MVC的方法名称以生成URL该方法的不打算
没有办法做到这一点,因为方法解决方法总是适用于返回类型和参数的组合,但不仅限于返回类型。我刚刚在其他帖子中发布的原因是,问题在这里。为什么C#不仅不同的返回类型提供方法解析原因是以下...
public class Test{
public int DoMethod(){ return 2; }
public string DoMethod() { return "Name"; }
}
Test t;
int n = t.DoMethod(); // 1st method
string txt = t.DoMethod(); // 2nd method
object x = t.DoMethod(); // DOOMED ... which one??
如果你注意到,在最后声明中,编程语言有选择哪种方法没有正确的解决方案。
这是完全一样的原因,下面的代码无法正常工作......
public class Test{
public T ReturnEmpty<T>() { return default(T); }
public T ReturnEmpty<T>(T x) { return x; }
}
Test t = new Test();
int n = t.ReturnEmpty(); <--- does not work..
the reson check next statement...
object k = t.ReturnEmpty(); <--- which one...
int l = t.ReturnEmpty<int>(); <--- this is correct....
string m = t.ReturnEmpty("Do Test"); <-- this is correct...
所以再次,相同的解决方案,解决仅基于返回类型的方法为任何一个编译器解决方案abigious。编程语言与口头语言不同,因为它们的设计始终是“一种执行方式”,没有歧义,也没有上下文依赖关系。每个陈述都完全独立于上下文。
然而,你可以争辩说你有正确的返回类型,但事实并非总是如此,编译器需要强大的规则来编译和生成代码。
关于:object k = t.ReturnEmpty();编译器可能会在这一个上返回一个错误,说明没有办法隐式地定义需要在这里调用哪个方法。但是这会带来额外的复杂性。 此外键入推论不会工作,原因很明显... – Ray 2009-08-11 12:42:43
这个问题与方法解析无关,而是泛型类型参数解析,这是由C#编译器完全分开完成的。 – Noldorin 2009-08-11 12:43:13
@Ray,@Noldorin我知道这些错误,并且您是否调用泛型类型参数解析或方法重新解析,解析需求的规则不可能是模糊的,那就是我想解释的是,这不可能由替代例。 – 2009-08-11 12:55:07
简单的答案是否定的,在最新版本的C#中这是不可能的。方法调用的泛型类型参数的推理只是不够聪明,不足以实现您传递的方法返回int
。因此,你不得不自己指定它。
通过阅读C# Language Specification的部分14.5.5.1
可以找到长答案。虽然它在这个特定情况下并不直接,但它确实暗示了你所希望的那种类型推断是不可能的。请仔细阅读该部分和25
中的相应文字,并且您应该知道所有关于泛型类型参数及其推断的知识。
希望有所帮助。如果您需要对特定部件进行任何说明,请告知我们。
你可以添加这不可能<>类接受<int, TResult>
通话?
public static void Example(Expression<Func<TSource, Func<int, TResult>>> function)
{ Process(function as MethodCallExpression); }
我想我真的不明白的问题是什么?如何使用委托? – chills42 2009-08-07 19:06:56
问题是我怎么可以可以我推断出T1到T4的参数类型,将代码复制到程序中并编译。 – bleevo 2009-08-08 00:32:19