Func <t,t =“”>到T </t,>的通用隐式转换

时间:2014-02-28 00:40:43

标签: c# generics

所以我有这段代码,受到javascript自我初始化匿名函数的启发。

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 Contact,Contact 对我来说有点啰嗦。 我希望编译器通过最后传入的参数类型计算出转换。

这样的事情:

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));
}

也许有一种聪明的扩展方法可以实现这种语法糖?

我最终在没有命名空间的类中使用了follow:

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);
    }
}

2 个答案:

答案 0 :(得分:7)

只需简单并避免使用lambda:

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;
}

答案 1 :(得分: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的忠实粉丝)