标签: method-group

方法推断不适用于方法组

考虑

void Main()
{
    var list = new[] {"1", "2", "3"};
    list.Sum(GetValue); //error CS0121
    list.Sum(s => GetValue(s)); //works !
}

double GetValue(string s)
{
    double val;
    double.TryParse(s, out val);
    return val;
}
Run Code Online (Sandbox Code Playgroud)

CS0121错误的描述是

以下方法或属性之间的调用是不明确的: 'System.Linq.Enumerable.Sum<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string,decimal>)''System.Linq.Enumerable.Sum<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string,decimal?>)'

我不明白的是,什么信息s => GetValue(s)给编译器根本GetValue不-不是前者,后者的语法糖?

c# type-inference .net-4.0 method-group

11
推荐指数
2
解决办法
1762
查看次数

Visual Studio 2015扩展方法调用方法组

我有一个类似的扩展方法

public static void RemoveDetail<TMaster, TChild>(this TMaster master, TChild child)
        where TMaster : class, IMaster<TChild>
        where TChild : class, IDetail<TMaster>;
Run Code Online (Sandbox Code Playgroud)

我有两节课

public class Principal : IMaster<Permission>
{
        public virtual IEnumerable<Permission> Permissions { get; }
}
Run Code Online (Sandbox Code Playgroud)

public class Permission : IDetail<Principal>
Run Code Online (Sandbox Code Playgroud)

我从方法接受的Action中调用RemoveDetailpublic static void Foreach<T>(this IEnumerable<T> source, Action<T> action);:

aPrincipal.Permissions.Foreach(x => aPrincipal.RemoveDetail(x));
Run Code Online (Sandbox Code Playgroud)

ReSharper建议我用方法组替换这个调用

aPrincipal.Permissions.Foreach(aPrincipal.RemoveDetail);
Run Code Online (Sandbox Code Playgroud)

这在VS2013和之前的版本中运行良好但在VS2015中编译失败了

'Principal'不包含'RemoveDetail'的定义,并且没有扩展方法'RemoveDetail'可以找到接受类型'Principal'的第一个参数(你是否缺少using指令或汇编引用?)

有人有建议吗?我是否必须更新所有用法并使ReSharper避免这种替换?

c# extension-methods method-group visual-studio-2015

11
推荐指数
1
解决办法
599
查看次数

将方法组转换为表达式

我试图弄清楚是否有一个简单的语法将方法组转换为表达式.使用lambdas似乎很容易,但它并没有转化为方法:

特定

public delegate int FuncIntInt(int x);
Run Code Online (Sandbox Code Playgroud)

以下所有内容均有效:

Func<int, int> func1 = x => x;
FuncIntInt del1 = x => x;
Expression<Func<int, int>> funcExpr1 = x => x;
Expression<FuncIntInt> delExpr1 = x => x;
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试使用实例方法,它会在表达式中分解:

Foo foo = new Foo();
Func<int, int> func2 = foo.AFuncIntInt;
FuncIntInt del2 = foo.AFuncIntInt;
Expression<Func<int, int>> funcExpr2 = foo.AFuncIntInt; // does not compile
Expression<FuncIntInt> delExpr2 = foo.AFuncIntInt;      //does not compile
Run Code Online (Sandbox Code Playgroud)

最后两个都无法使用"无法将方法组'AFuncIntInt'转换为非委托类型'System.Linq.Expressions.Expression <...>'进行编译.您是否打算调用该方法?"

那么在表达式中捕获方法组有一个很好的语法吗?

谢谢,阿恩

lambda expression method-group c#-3.0

8
推荐指数
1
解决办法
6013
查看次数

重载的方法组参数会混淆重载决策?

以下调用重载Enumerable.Select方法:

var itemOnlyOneTuples = "test".Select<char, Tuple<char>>(Tuple.Create);
Run Code Online (Sandbox Code Playgroud)

失败并出现歧义错误(为清晰起见,删除了名称空间):

The call is ambiguous between the following methods or properties: 
'Enumerable.Select<char,Tuple<char>>
           (IEnumerable<char>,Func<char,Tuple<char>>)'
and 
'Enumerable.Select<char,Tuple<char>>
          (IEnumerable<char>, Func<char,int,Tuple<char>>)'
Run Code Online (Sandbox Code Playgroud)

我当然可以理解为什么明确指定类型参数会导致歧义(两个都会应用重载),但是在这样做后我没有看到.

对我来说似乎很清楚,目的是调用第一个重载,方法组参数解析为Tuple.Create<char>(char).第二个重载不应该适用,因为没有任何 Tuple.Create重载可以转换为期望的Func<char,int,Tuple<char>>类型.我猜测编译器很困惑Tuple.Create<char, int>(char, int),但它的返回类型是错误的:它返回一个二元组,因此不能转换为相关Func类型.

顺便说一句,以下任何一个使编译器开心:

  1. 为method-group参数指定一个type-argument :( Tuple.Create<char>也许这实际上是一个类型推断问题?).
  2. 使参数成为lambda表达式而不是方法组:x => Tuple.Create(x).(在Select通话中使用类型推断很好).

不出所料,尝试以Select这种方式调用其他重载也会失败:

var itemIndexTwoTuples = "test".Select<char, Tuple<char, int>>(Tuple.Create);
Run Code Online (Sandbox Code Playgroud)

这里的确切问题是什么?

c# method-group overload-resolution c#-4.0

8
推荐指数
2
解决办法
2231
查看次数

这个ReSharper片段"转换为方法组"实际上是做什么的?

在此输入图像描述

更改前的代码:

List<ProductBrandModel> model = brands.Select(item => Mapper.Map<ProductBrand, ProductBrandModel>(item)).ToList();
Run Code Online (Sandbox Code Playgroud)

改进后的代码:

List<ProductBrandModel> model = brands.Select(Mapper.Map<ProductBrand, ProductBrandModel>).ToList();
Run Code Online (Sandbox Code Playgroud)

这是做什么的?它是否隐式在brands集合中的每个项目上运行映射?

.net c# resharper method-group

8
推荐指数
1
解决办法
5300
查看次数

为什么委托必须是静态的?

在下面的代码中,我必须声明方法,MdrResponseInterpreter static否则我有编译错误.

class.... {

    private StandardBuilder _mdrResponseBuilder = 
      new StandardBuilder(MdrResponseInterpreter);

    public static bool MdrResponseInterpreter(DNMessageDeliverer builder, 
                                              DNFieldSet message)
    {
        // .... work
    }
Run Code Online (Sandbox Code Playgroud)

为什么?由于_mdrResponseBuilder不是静态的,我希望MdrResponseInterpreter应该能够访问this

c# delegates initializer method-group

8
推荐指数
2
解决办法
1014
查看次数

VB.NET中的方法组?

James Michael Hare最近写了一篇关于Char静态方法的博客文章.他谈到使用方法组来编写不那么冗长的LINQ:

if (myString.Any(c => char.IsLower(c))) { xyzzy(); }
if (myString.Any(char.IsLower)) { xyzzy(); } // Less wordy FTW!
Run Code Online (Sandbox Code Playgroud)

VB.NET中的等价物是:

If myString.Any(Function(c) Char.IsLower(c)) Then xyzzy()
If myString.Any(Char.IsLower) Then xyzzy() 'Compiler error
Run Code Online (Sandbox Code Playgroud)

可悲的是,我不能在这里做相当于C#...编译器告诉我Overload resolution failed because no accessible 'IsLower' accepts this number of arguments......悲伤.我认为这可能是由于我已经Option Strict开始,但唉,这也不起作用.

我假设方法组在VB.NET中不可用... VB.NET中是否有类似的功能?或者为什么不能(不会)在VB.NET中完成的任何特殊原因?

vb.net method-group

7
推荐指数
1
解决办法
778
查看次数

为什么将方法组传递给重载方法会导致在lambda中调用方法时出现歧义?

// Compiler Error当在所有其他情况下正确推断出类型时,为什么不能在下面的代码中标记的行上推断出要调用的正确重载?

public static class Code {

    private static void Main() {

        OverloadedMethod<string>(() => new Wrapper<string>()); // OK
        OverloadedMethod<string>(() => MethodReturningWrappedString()); // OK
        OverloadedMethod<string>((Func<Wrapper<string>>)MethodReturningWrappedString); // OK
        OverloadedMethod<string>(MethodReturningWrappedString); // Compiler Error

    }

    public static Wrapper<string> MethodReturningWrappedString() {
        return new Wrapper<string>();
    }

    public static void OverloadedMethod<T>(Func<Wrapper<T>> func) where T : class {
    }

    public static void OverloadedMethod<T>(Func<T> func) where T : class {
    }

    public struct Wrapper<T> where T : class {
    }

}
Run Code Online (Sandbox Code Playgroud)

这是编译器错误:

The call is ambiguous between …
Run Code Online (Sandbox Code Playgroud)

c# lambda overloading method-group

5
推荐指数
1
解决办法
114
查看次数

使用分配代理时出错?: 句法

我已经创建了一个委托和两个匹配的方法.

private delegate bool CharComparer(char a, char b);

// Case-sensitive char comparer
private static bool CharCompare(char a, char b)
{
    return (a == b);
}

// Case-insensitive char comparer
private static bool CharCompareIgnoreCase(char a, char b)
{
    return (Char.ToLower(a) == Char.ToLower(b));
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用以下语法将这些方法中的任何一个分配给委托时(请注意,此代码位于同一类的静态方法中):

CharComparer isEqual = (ignoreCase) ? CharCompareIgnoreCase : CharCompare;
Run Code Online (Sandbox Code Playgroud)

我收到错误:

无法确定条件表达式的类型,因为"方法组"和"方法组"之间没有隐式转换

我可以使用常规if ... else语句来完成这项任务,它工作得很好.但我不明白为什么我不能使用更紧凑的版本,我不明白错误信息.有谁知道这个错误的含义?

c# delegates method-group

4
推荐指数
1
解决办法
153
查看次数

将方法传递给LINQ查询

在我正在进行的项目中,我们有许多静态表达式,当我们在它们上面调用Invoke方法并将lambda表达式的参数传递给它时,我们必须在本地范围内带一个变量.

今天,我们声明了一个静态方法,其参数正是查询所期望的类型.所以,我的同事和我正在搞乱,看看我们是否可以在查询的Select语句中使用此方法来执行项目,而不是在整个对象上调用它,而不将其带入本地范围.

它奏效了!但我们不明白为什么.

想象一下像这样的代码

// old way
public static class ManyExpressions {
   public static Expression<Func<SomeDataType, bool> UsefulExpression {
      get {
         // TODO implement more believable lies and logic here
         return (sdt) => sdt.someCondition == true && false || true; 
      }
   }
}

public class ARealController : BaseController {

   /* many declarations of important things */

   public ARealClass( /* many ninjected in things */) {
      /* many assignments */
   }

   public JsonNet<ImportantDataResult> getSomeInfo(/* many useful parameter */) {

      var usefulExpression = …
Run Code Online (Sandbox Code Playgroud)

c# linq method-group

4
推荐指数
1
解决办法
4451
查看次数