none
关于Func<>的问题 RRS feed

  • 问题

  • 如果我有一个方法:

    void funcA(Func<classA, int> n)

    然后classA和classB是能隐式转换的。

    那么我调用这个方法时传入的参数可以是Func<classB, int>类型的吗?

    方法内是不是会自动将参数Func<classB, int>转成Func<classA, int>?

    2014年4月22日 2:58

全部回复

  • 这其实是.net 4.0中的逆变。假如classA能够转换为classB(classA继承classB),则调用void funcA(Func<classA, int> n)时参数可以是Func<classB, int>。方法内不会自动转换参数,在Func<classB, int>被调用时,传进去的参数仍然是classA(因为classA能够转换成classB,所以传classA给classB是合法的)。

    关于逆变,可以参考:

    http://msdn.microsoft.com/zh-cn/library/ms173174(VS.80).aspx


    • 已编辑 lapheal 2014年4月22日 6:39
    2014年4月22日 6:34
  • 我所说的情况classA和classB不是继承关系,而是通过implicit operator让classA和classB可隐式转换。

    这样逆变仍然适用吗?

    2014年4月22日 7:58
  • 我所说的情况classA和classB不是继承关系,而是通过implicit operator让classA和classB可隐式转换。

    这样逆变仍然适用吗?

    这样应该是不行的。你可以写代码测试以下。
    2014年4月22日 9:41
  • 直接这样做确实不行。

    不过可以通过lamda expression来实现。

    2014年5月4日 2:06
  • 你好:

    可以把你的实现代码贴出来吗?这样可以帮助更多的人解决类似的问题。

    非常感谢!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年5月4日 3:30
    版主
  •  

    classA和classB都包含成员a。

             Expression<Func<classA, bool>> ExpressionA = (classA p) =>p.a.Equals(1);

              var ExpressionParameterP = Expression.Parameter(typeof(classB), "p");

              Expression<Func<classB, bool>> result = Expression.Lambda<Func<classB, bool>>
         (FuncExpressionA.Body,  ExpressionParameterP );

    这样,简单的Lambda表达式是可以转换的,但嵌套的貌似不行,如:

              Expression<Func<classA,Expression<Func<classA, bool>>>> ExpressionA =(classA m)=> (classA p) =>p.a.Equals(m.a);



    2014年5月8日 2:58
  •  

    classA和classB都包含成员a。

             Expression<Func<classA, bool>> ExpressionA = (classA p) =>p.a.Equals(1);

              var ExpressionParameterP = Expression.Parameter(typeof(classB), "p");

              Expression<Func<classB, bool>> result = Expression.Lambda<Func<classB, bool>>
         (FuncExpressionA.Body,  ExpressionParameterP );

    这样,简单的Lambda表达式是可以转换的,但嵌套的貌似不行,如:

              Expression<Func<classA,Expression<Func<classA, bool>>>> ExpressionA =(classA m)=> (classA p) =>p.a.Equals(m.a);



    请参考我给你回复的另外一个问题,如果classA和classB中都有相同的变量/属性/方法,可以使用dynamic类型来定义:

    Func<dynamic, bool>

    2014年5月8日 3:50
  • 如果dynamic有像泛型约束一样的东西就好了,能在编译时做检查,然后有代码提示至少是提示约束内合法的成员。
    2014年5月8日 6:26
  • 2014年5月10日 8:00
    版主