Вызов метода расширения Visual Studio 2015 как группа методов

У меня есть метод расширения, например

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

И у меня есть два класса

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

и

public class Permission : IDetail<Principal>

Я вызываю RemoveDetail из действия, принятого методом public static void Foreach<T>(this IEnumerable<T> source, Action<T> action);:

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

ReSharper предложит мне заменить этот вызов группой методов, например

aPrincipal.Permissions.Foreach(aPrincipal.RemoveDetail);

Это отлично работало в VS2013 и предыдущем, но не удалось выполнить компиляцию в VS2015 с помощью

"Принципал" не содержит определения для "RemoveDetail", и не может быть найден метод расширения "RemoveDetail", принимающий первый аргумент типа "Принципал" (вам не хватает директивы использования или ссылки на сборку?)

У кого-нибудь есть предложение? Должен ли я обновлять все способы использования и заставить ReSharper избегать этой замены?

Ответ 1

Я смог воспроизвести вашу проблему

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

    }
}

Resharper ничего не предлагает. поэтому, вероятно, вам нужно обновить Resharper до более новой версии. вероятно, была ошибкой, которая теперь исправлена.

Если это не так, как вы. то вам нужно добавить больше информации.

Также компилятор дает такую ​​же ошибку, когда я пытаюсь преобразовать ее в группу методов. Таким образом, этот вопрос может остаться: Почему компилятор не может этого сделать?

Edit:

Чтобы устранить эту проблему, вы должны вызвать метод RemoveDetail изнутри Principal. поэтому сделайте свой класс Principal таким.

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

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

Я думаю, что существует некоторый двусмысленный внутренний компилятор (возможно, ошибка), который не может распознать метод RemoveDetail. как компилятор пытается найти его внутри Principal. поэтому вы можете исправить его созданием RemoveDetail внутри Principal и вызвать там статический RemoveDetail.

Изменить 2:

Проблема связана с общим типом.

where TMaster : class, IMaster<TChild>

Это заставляет компилятор смотреть на класс, который реализует IMaster<TChild> и thats Principal. если вы удалите это предложение where, оно решит проблему. иначе компилятор ожидает, что он должен быть Principal.

Если вы используете лямбда, вы удаляете эту двусмысленность.

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!

Итак, это ошибка С# 6

Ответ 3

Я не вижу, как это работает в VS2013. RemoveDetail - это метод TMethod не вашего Action MyClass.

Это должно быть что-то вроде

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