我正在开发一个个人项目来构建一个真值表生成器,重点是收集/巩固我对逻辑等价学习的知识。
因此,我试图以一种 C#Function 作为参数的方式编写它。我稍后会把它变成"build a compiler project",但是现在我想要了解更多关于代表,元编程以及在逻辑等价方面的乐趣。
所以,我想弄清楚的是语法是如何定义一个需要1到N个布尔参数的委托,这样我就可以避免像这样违反DRY ......
public delegate bool OneArgFunc(bool arg1);
public delegate bool TwoArgFunc(bool arg1, bool arg2);
public delegate bool ThreeArgFunc(bool arg1, bool arg2, bool arg3);
public delegate bool OuchieThisIsStartingToHurt(bool arg, bool arg, bool arg...);
...而且我不相信下面会这样做,因为" ListOnlyFunc"将boolean类型的 list 作为单个参数 - 当我想要的是一个可以接受带有两个布尔参数的布尔函数的委托,或者一个带有1200个布尔参数的函数。
public delegate bool ListOnlyFunc(bool[] args); // Nope!
我想避免后者的部分原因是我希望能够从函数中提取参数名称(而不是显示通用的索引参数)。例如,如果我在下面运行,我应该看到" foo,baz,turkey"在输出窗口中;我不想简单地得到参数数量的计数并输出索引(" 1,2,3和#34;)。
public CSharpBoolDelegate MyFunc(bool foo, bool baz, bool turkey)
{
//does things
}
public class Program
{
static void Main(string[] args)
{
IStatementSniffer sniffer = new CSharpFunctionSniffer(myFunc);
sniffer.printArgs();
}
}
如果您有任何关于如何处理此问题的提示(或者如果可能的话),我们将非常感谢您的建议。 :)
谢谢,
克里斯
答案 0 :(得分:0)
你可以像这样定义param方法委托
public delegate bool SumParameters(params bool[] values)
如果你想要参数的名字,你可以使用字典,这个解决方案已经由@Rob
提出 public delegate bool SumParameters(Dictionary<string,bool> values)
答案 1 :(得分:0)
因为你想要参数名称,所以它有点乱。根据你想做的事情,你可以这样写:
public void MyFunc(bool? argOne = null,
bool? argTwo = null,
bool? argThree = null,
bool? argFour = null,
bool? argFive = null)
{
}
你可以这样称呼它:
MyFunc(true);
MyFunc(true, false);
MyFunc(true, false, true);
MyFunc(true, false, true, false);
然而,这引起了一些并发症。例如,这是否有效?
MyFunc(null, true)
这里我们只提供了argTwo
,但是你也必须提供所有以前的参数(例如,跳过参数无效)。
或者,您可以这样做:
public void MyFunc(Dictionary<string, bool> args)
{
}
并称之为:
MyFunc(new Dictionary<string, bool> { { "arg1", true }, {"arg2", true } });
答案 2 :(得分:0)
如果您只想获得有关该方法的一些信息,那么您需要的是一个接受Delegate
作为参数的方法:
public static string MethodSignature(Delegate del) => del.Method.ToString();
这样做的缺点是方法不 Delegate
(或delegate
),因此您必须强制转换为Func<...>
,Action<...>
或其他合适的代表类型,如下所示:
void Main()
{
Console.WriteLine(MethodSignature((Func<bool, bool, bool>)testFunc));
Console.WriteLine(MethodSignature((Action<bool, bool[]>)testAction));
}
bool testFunc(bool a, bool b) => a || b;
void testAction(bool a, bool[] b) { };
当然,如果您已经拥有delegate
,则不需要演员。
无论哪种方式,一旦你有delegate
参数名称可用:
public static string ParameterNames(Delegate del) =>
string.Join(", ", del.Method.GetParameters().Select(p => p.Name));