[英]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. 所以你可以
RemoveDetail
在Principal
创建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
. RemoveDetail
是RemoveDetail
的一种方法, TMethod
不是你的Action MyClass
。
It should be something like 应该是这样的
z.ForEach(x => master.RemoveDetail(x);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.