简体   繁体   English

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

[英]Visual Studio 2015 extension method call as method group

I have an extension method like 我有一个类似的扩展方法

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

And I have two classes 我有两节课

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

and

public class Permission : IDetail<Principal>

I call RemoveDetail from an Action accepted by method public static void Foreach<T>(this IEnumerable<T> source, Action<T> action); 我从方法public static void Foreach<T>(this IEnumerable<T> source, Action<T> action);接受的Action中调用RemoveDetail public static void Foreach<T>(this IEnumerable<T> source, Action<T> action); :

aPrincipal.Permissions.Foreach(x => aPrincipal.RemoveDetail(x));

ReSharper suggest me to replace this call with method group like ReSharper建议我用方法组替换这个调用

aPrincipal.Permissions.Foreach(aPrincipal.RemoveDetail);

This worked fine in VS2013 and previous but it fails on compilation in VS2015 with 这在VS2013和之前的版本中运行良好但在VS2015中编译失败了

'Principal' does not contain a definition for 'RemoveDetail' and no extension method 'RemoveDetail' accepting a first argument of type 'Principal' could be found (are you missing a using directive or an assembly reference?) 'Principal'不包含'RemoveDetail'的定义,并且没有扩展方法'RemoveDetail'可以找到接受类型'Principal'的第一个参数(你是否缺少using指令或汇编引用?)

Anyone has a suggestion? 有人有建议吗? Do I have to update all of the usages and make ReSharper to avoid this replacement? 我是否必须更新所有用法并使ReSharper避免这种替换?

I was able to reproduce your problem 我能够重现你的问题

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)
    {

    }
}

The resharper does not suggest anything. resharper没有提出任何建议。 so probably you have to update your Resharper to newer version. 所以可能你必须将你的Resharper更新到更新的版本。 probably was a bug which is fixed now. 可能是一个现在修复的错误。

If this is not like the way you do. 如果这不像你那样做。 then you have to put more information. 那么你必须提供更多信息。

Also Compiler gives same error when i try to convert it to method group. 当我尝试将其转换为方法组时,编译器也会出现相同的错误。 So this question may remain: Why Compiler cant do this? 所以这个问题可能仍然存在: 为什么编译器不能这样做?

Edit: 编辑:

To fix this problem you have to call the RemoveDetail method from inside Principal. 要解决此问题,您必须从Principal内部调用RemoveDetail方法。 so make your Principal class like this. 所以让你的校长班这样。

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

    public void RemoveDetail(Permission p)
    {
        Class.RemoveDetail(this, p);
    }
}

I think there is kind of ambiguous inside compiler (Possibly bug) that cant recognize RemoveDetail method. 我认为有一种模糊的内部编译器(可能是bug)无法识别RemoveDetail方法。 how ever compiler tries to find it inside Principal . 编译器如何尝试在Principal找到它。 so you can fix it with creating RemoveDetail inside Principal and call a static RemoveDetail from there. 所以你可以RemoveDetailPrincipal创建RemoveDetail并从那里调用静态RemoveDetail来修复它。

Edit 2: 编辑2:

The problem is generic type constraint. 问题是泛型类型约束。

where TMaster : class, IMaster<TChild>

This makes compiler to look at class which implements IMaster<TChild> and thats Principal . 这使得编译器可以查看实现IMaster<TChild>IMaster<TChild> Principal if you remove this where clause it will solve the problem. 如果你删除这个where子句,它将解决问题。 otherwise the compiler expects that it should be Principal . 否则编译器期望它应该是Principal

If you use lambda you remove this ambiguity. 如果你使用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!

So thats a C#6 bug 这就是C#6的错误

I gave a feedback on this subject to Microsoft on September the 3rd 2015 here: 我在2015年9月3日向Microsoft提供了有关此主题的反馈:
https://connect.microsoft.com/VisualStudio/feedback/details/1747835/visual-studio-2015-extension-method-call-as-method-group https://connect.microsoft.com/VisualStudio/feedback/details/1747835/visual-studio-2015-extension-method-call-as-method-group

Today I got this feedback from Neal [MSFT]: 今天我收到了Neal [MSFT]的反馈:

This is fixed in VS2015 Update 1. 这已在VS2015 Update 1中修复。
It is tracked here: https://github.com/dotnet/roslyn/issues/4970 它在这里被跟踪: https//github.com/dotnet/roslyn/issues/4970

I don't see how it worked in VS2013. 我不知道它在VS2013中是如何工作的。 RemoveDetail is a method of TMethod not your Action MyClass . RemoveDetailRemoveDetail的一种方法, TMethod不是你的Action MyClass

It should be something like 应该是这样的

z.ForEach(x => master.RemoveDetail(x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM