2009-08-07 73 views
3

下面是一些用于传递对包含字符串作为参数的方法的引用的代码,此问题的目的是围绕使用泛型否定需要定义实际的类型!将方法传递到需要方法名称的另一个方法

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 
    } 
} 
+0

我想我真的不明白的问题是什么?如何使用委托? – chills42 2009-08-07 19:06:56

+0

问题是我怎么可以可以我推断出T1到T4的参数类型,将代码复制到程序中并编译。 – bleevo 2009-08-08 00:32:19

回答

0

它看起来越来越像这种无法做到:(

+0

经过进一步的研究,没有简单的方法来支持这种方法,我将使用T4模板进行探索。 – bleevo 2009-08-17 00:37:53

+0

这就是Noldorin的回答,为什么不接受他更详细的答案? – nawfal 2013-04-27 14:57:28

0

最明确,最强的打字我能想出这个职位的问题部分上市:

Why is there not a fieldof or methodof operator in C#?

要顶到,我需要更多地了解你的目标是什么(这里有更大的图片)。

+0

这里的最终目标是通过查找基于类型的路由来传递ASP.NET MVC的方法名称以生成URL该方法的不打算(“的MyMethod”),但在控制器和名称的相当(C => c.MyMethod),其中的参数的类型的MyMethod取心不是重要或它的返回只需输入它的名称即可。 – bleevo 2010-07-10 04:08:03

0

没有办法做到这一点,因为方法解决方法总是适用于返回类型和参数的组合,但不仅限于返回类型。我刚刚在其他帖子中发布的原因是,问题在这里。为什么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。编程语言与口头语言不同,因为它们的设计始终是“一种执行方式”,没有歧义,也没有上下文依赖关系。每个陈述都完全独立于上下文。

然而,你可以争辩说你有正确的返回类型,但事实并非总是如此,编译器需要强大的规则来编译和生成代码。

+0

关于:object k = t.ReturnEmpty();编译器可能会在这一个上返回一个错误,说明没有办法隐式地定义需要在这里调用哪个方法。但是这会带来额外的复杂性。 此外键入推论不会工作,原因很明显... – Ray 2009-08-11 12:42:43

+0

这个问题与方法解析无关,而是泛型类型参数解析,这是由C#编译器完全分开完成的。 – Noldorin 2009-08-11 12:43:13

+0

@Ray,@Noldorin我知道这些错误,并且您是否调用泛型类型参数解析或方法重新解析,解析需求的规则不可能是模糊的,那就是我想解释的是,这不可能由替代例。 – 2009-08-11 12:55:07

3

简单的答案是否定的,在最新版本的C#中这是不可能的。方法调用的泛型类型参数的推理只是不够聪明,不足以实现您传递的方法返回int。因此,你不得不自己指定它。

通过阅读C# Language Specification的部分14.5.5.1可以找到长答案。虽然它在这个特定情况下并不直接,但它确实暗示了你所希望的那种类型推断是不可能的。请仔细阅读该部分和25中的相应文字,并且您应该知道所有关于泛型类型参数及其推断的知识。

希望有所帮助。如果您需要对特定部件进行任何说明,请告知我们。

+0

虽然不是一个解决方案,我想你已经证实了我相信这心不是可能的,我不打算T4模板和大量的方法重载的是唯一的方法:( – bleevo 2009-08-14 05:48:09

+0

是啊,除非我误会了,没有解决问题的方法(而不是直接的,至少)你是否可能澄清到底为什么你必须有推断的类型,而不是明确指定呢? – Noldorin 2009-08-14 11:36:53

0

你可以添加这不可能<>类接受<int, TResult>通话?

public static void Example(Expression<Func<TSource, Func<int, TResult>>> function) 
{ Process(function as MethodCallExpression); } 
+0

正如你会看到这个方法的问题是不可接受的,因为我必须为每种类型和类型的组合做到这一点。 – bleevo 2009-08-14 05:46:59

+0

对不起,我误解了。我应该在回答之前重新阅读这个问题。我不认为有一个解决方案适合你的问题约束 – ongle 2009-08-14 12:45:05

相关问题