有没有办法限制C#类中的函数只使用特定的签名?

有没有办法限制C#类中的函数只使用特定的签名?,c#,compile-time,C#,Compile Time,我正在编写一个类,理想情况下应该有多个具有相同签名的方法。如果所有方法都遵循相同的签名,是否有办法强制类检查其方法 如果检查可以在编译时/构建期间完成,这将是理想的 如果您假定签名为int(string,int,char) 不直接。您可以使用Roslyn为其编写分析器,也可以编写通过反射检查签名的单元测试。您可以进行单元测试: [TestMethod] public void Conditions_MethodsHaveCorrectSignature() {

我正在编写一个类,理想情况下应该有多个具有相同签名的方法。如果所有方法都遵循相同的签名,是否有办法强制类检查其方法

如果检查可以在编译时/构建期间完成,这将是理想的

如果您假定签名为
int(string,int,char)


不直接。您可以使用Roslyn为其编写分析器,也可以编写通过反射检查签名的单元测试。

您可以进行单元测试:

    [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());
        }
    }
[TestMethod]
公共无效条件(签名)
{
var whitelist=新列表{“Finalize”,“MemberwiseClone”};
var t=类型(条件);
var m=t.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
foreach(m.Where(x=>!whitelist.Contains(x.Name))中的变量项)
{
Assert.AreEqual(typeof(int),item.ReturnType);
AreEquivalent(新列表{typeof(string)、typeof(int)、typeof(char)},
item.GetParameters().Select(x=>x.ParameterType.ToList());
}
}

这是一种欺骗,但是如果您要求开发人员注册他们的方法,您可以通过要求方法与委托匹配来强制编译时错误

这本质上就是事件处理程序和回调的工作方式

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;
        }
    }
}

为什么您希望它抛出,为什么不在编译时提取它,在这种情况下,只需使用一个像接口一样的契约。为什么您希望这样?这是一个非常不寻常的请求,表明实际问题有所不同。@PanagiotisKanavos我以前需要这样做…@MarcGravel为什么?我能理解实现命令或类似的东西,这些可以通过接口实现。编译器无法强制所有方法都具有相同的签名,尽管我永远不想与@MarcGravel相矛盾,但是“我希望方法签名标准化,这样我可以更轻松地调用它们的代码”听起来像是接口的工作,或者是一种快速而肮脏的方式-将所有方法分配给
Func
。这将导致编译器抱怨。很脏though@PanagiotisKanavos不过这并不可怕——特别是如果你通过反射激活它们。。。
Dictionary
变得非常诱人,f#的函数组合基本上是通过链接
Func
s来工作的,所以它可能不是一个肮脏的解决方案
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;
        }
    }
}