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

dva*_*bna 11 c# extension-methods method-group 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避免这种替换?

M.k*_*ary 7

我能够重现你的问题

public interface IDetail<T>
{

}

public interface IMaster<T>
{

}

public class MyClass
{
    public void method()
    {
        Principal aPrincipal = new Principal();
        aPrincipal.Permissions.Foreach(x => aPrincipal.RemoveDetail(x)); // No suggestion from resharper
    }
}

public class Permission : IDetail<Principal>
{

}

public class Principal : IMaster<Permission>
{
    public virtual IEnumerable<Permission> Permissions { get; }
}

public static class Class
{
    public static void RemoveDetail<TMaster, TChild>(this TMaster master, TChild child)
        where TMaster : class, IMaster<TChild>
        where TChild : class, IDetail<TMaster>
    {

    }

    public static void Foreach<T>(this IEnumerable<T> source, Action<T> action)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

resharper没有提出任何建议.所以可能你必须将你的Resharper更新到更新的版本.可能是一个现在修复的错误.

如果这不像你那样做.那么你必须提供更多信息.

当我尝试将其转换为方法组时,编译器也会出现相同的错误.所以这个问题可能仍然存在:为什么编译器不能这样做?

编辑:

要解决此问题,您必须RemoveDetail从Principal内部调用该方法.所以让你的校长班这样.

public class Principal : IMaster<Permission>
{
    public virtual IEnumerable<Permission> Permissions { get; }

    public void RemoveDetail(Permission p)
    {
        Class.RemoveDetail(this, p);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为有一种模糊的内部编译器(可能是bug)无法识别RemoveDetail方法.怎么编译器试图在里面找到它Principal.所以你可以通过创建RemoveDetail内部PrincipalRemoveDetail从那里调用静态来修复它.

编辑2:

问题是泛型类型约束.

where TMaster : class, IMaster<TChild>
Run Code Online (Sandbox Code Playgroud)

这使得编译器可以查看实现的类IMaster<TChild>和那个Principal.如果你删除这个where子句,它将解决问题.否则编译器应该期望它Principal.

如果你使用lambda,你可以消除这种歧义.

aPrincipal.RemoveDetail // compiler expects property/field/method in Principal
                        // but compiler forgets method group and static generic method!
x => aPrincipal.RemoveDetail(x) // this is no more like property or field
                                //but a method that is considered static generic method!
Run Code Online (Sandbox Code Playgroud)

这就是C#6的错误

  • 新的C#编译器必定存在错误! (3认同)