2014-02-28 47 views
1

所以我有这段代码,受到JavaScript自我初始化匿名函数的启发。Func <T, T>通用隐式转换为T

public static Contact Login(string username, string passwordHash = null) 
{ 
    return ((Func<Contact, Contact>)(c => { 
      if (c != null) { 
       var context = new CurrentContext(); 
       context.Contact = c; 
       context.Save(); 
      } 
      return c; 
     }))(GetContactFromDatabase(username) ?? GetContactFromWebService(username, passwordHash)); 
} 

它的伟大工程,但Func键联系,联系是有点长篇大论对我的胃口。 我希望编译器通过最后传入的参数类型来进行转换。

事情是这样的:

public class AF<T> 
{ 
    public static implicit operator T(Func<T, T> fun) 
    { 
     return fun(); 
    } 
} 

但它不会编译。我想到了一个类不像c#tuple类的类,它用15个不同的T来定义自己。

最终代码看起来是这样的:

public static Contact Login(string username, string passwordHash = null) 
{ 
    return ((AF)(c => { 
      if (c != null) { 
       var context = new CurrentContext(); 
       context.Contact = c; 
       context.Save(); 
      } 
      return c; 
     }))(GetContactFromDatabase(username) ?? GetContactFromWebService(username, passwordHash)); 
} 

也许有能做到这一点语法糖聪明的扩展方法?

我最终使用的一类后续没有命名空间:

public delegate T F<T>(T value); 

public static class GenericExtensions { 
    [DebuggerStepThrough] 
    public static T For<T>(this F<T> function, T value) { 
     return function(value); 
    } 
} 
+1

为什么?问题是为什么要这样做?如果将匿名代码块提取到单独的函数中,它看起来不会更具可读性吗?对不起,但我在第二个代码块中也没有看到任何“糖”。语法糖通常意味着一些优雅的代码片段,但上面的代码不是这种情况 –

+3

如果完全避免了lambda表达式并且以直接方式编写它,那么'Login'方法将更具可读性(并且实际上更简洁) 。 –

回答

0

你可以实现你的意图,如果你不使用匿名功能,但代表否则

public delegate int Contacts(int a, int b); 

    public static class TestClass 
    { 
     public static void Test() 
     {    
      Contacts contactsFunc = (Contacts)((a, b) => a + b); 
      contactsFunc(2, 3); 
      //less verbose mode 
      ((Contacts)((a, b) => a + b))(2,3); 
     } 
    } 

但我必须同意wdosanjos并告诉你不要使用lambdas。

边注:映射Javascript编程风格,C#可能不是最好的指南(免责声明:但我的Javascript没有大风扇)

7

简简单单就避免拉姆达:

public static Contact Login(string username, string passwordHash = null) 
{ 
    Contact c = GetContactFromDatabase(username) ?? GetContactFromWebService(username, passwordHash); 

    if (c != null) { 
     var context = new CurrentContext(); 
     context.Contact = c; 
     context.Save(); 
    } 

    return c; 
} 
+0

你为什么说不要使用lambda?模式有什么问题? – user1909158

+2

使用lambda使这个代码更复杂。越简单越好。 Lambdas作为方法引用的类型安全抽象有一些好处,但这里不需要间接引用。 – recursive

相关问题