Есть ли способ ограничить функции в классе C #, чтобы использовать только определенную подпись? - PullRequest
2 голосов
/ 03 апреля 2019

Я пишу класс, который в идеале должен иметь несколько методов с одной и той же сигнатурой.Есть ли способ заставить класс проверять свои методы, если все они следуют одной и той же сигнатуре?

Было бы идеально, если бы проверка могла быть выполнена во время компиляции / во время сборки

Если вы предполагаете, что подпись int <methodName>(string, int, char)

public class Conditions {
        // no error
        int MethodA(string a, int b, char c)
        {
            return 0;
        }
        // no error
        int MethodB(string a, int b, char c)
        {
            return 1;
        }

        // should throw error because return type does not match signature
        string MethodC(string a, int b, char c)
        {
            return "Should throw an error for this function";
        }
    }
}

Ответы [ 3 ]

3 голосов
/ 03 апреля 2019

Вы можете сделать юнит-тест:

    [TestMethod]
    public void Conditions_MethodsHaveCorrectSignature()
    {
        var whitelist = new List<string> { "Finalize", "MemberwiseClone" };
        var t = typeof(Conditions);
        var m = t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);

        foreach (var item in m.Where(x => !whitelist.Contains(x.Name)))
        {
            Assert.AreEqual(typeof(int), item.ReturnType);

            CollectionAssert.AreEquivalent(new List<Type> { typeof(string), typeof(int), typeof(char) },
                item.GetParameters().Select(x => x.ParameterType).ToList());
        }
    }
3 голосов
/ 03 апреля 2019

Это своего рода обман, но если вы требуете, чтобы разработчик зарегистрировал их методы, вы можете вызвать ошибку времени компиляции, требуя, чтобы метод соответствовал делегату.

Это по существукак работают обработчики событий и обратные вызовы.

namespace Framework
{
    public delegate int MyApiSignature(int a, string b, char c);

    public class Core
    {
        static public void RegisterMethod(MyApiSignature method) 
        {
            //Doesn't even have to actually do anything
        }
    }
}


namespace Custom
{
    using Framework;

    class Foo
    {
        public Foo()
        {
            Core.RegisterMethod(MethodA);  //Works
            Core.RegisterMethod(MethodB);  //Compile-time error
        }

        public int MethodA(int a, string b, char c)
        {
            return 0;
        }

        public int MethodB(int a, string b, byte c)
        {
            return 0;
        }
    }
}
2 голосов
/ 03 апреля 2019

Не напрямую. Вы можете написать анализатор для него, используя Roslyn, или вы можете написать модульный тест, который проверяет подписи с помощью отражения.

...