C#:定义一个接受N个布尔参数的委托,以便稍后提取参数名称
本文关键字:参数 提取 布尔 定义 一个 | 更新日期: 2023-09-27 18:29:36
我正在进行一个个人项目,以构建真值表生成器,重点是收集/巩固我所学到的关于逻辑等价的知识。
因此,我试图以一种C#函数作为参数的方式来编写它。稍后我将把它变成一个"构建编译器项目",但现在我想了解更多关于委托、元编程的知识,并在学习过程中享受逻辑等价的乐趣
所以,我想弄清楚的是,我将如何在语法上定义一个接受1到N个布尔参数的Delegate,这样我就可以避免像这样违反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类型的列表作为一个参数——当我想要的是一个可以接受带有两个布尔参数的布尔函数或带有1200布尔参数的函数的委托时。
public delegate bool ListOnlyFunc(bool[] args); // Nope!
我希望避免后者的部分原因是,我希望能够从函数中提取参数名称(而不是显示通用索引参数)。例如,如果我运行下面的程序,我应该在输出窗口中看到"foo,baz,turkey";我不想简单地获取参数数量的计数并输出索引("1,2,3")。
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();
}
}
如果你对我如何处理这个问题有任何建议(或者如果可能的话),我们将不胜感激
谢谢,
Chris
由于需要参数名称,所以会有点混乱。根据你想做的事情,你可以写这样的东西:
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 } });
您可以定义类似的param方法委托
public delegate bool SumParameters(params bool[] values)
如果你想要参数的名称,你可以使用字典,这个解决方案已经由@Rob 提出
public delegate bool SumParameters(Dictionary<string,bool> values)
如果您只想获得有关该方法的一些信息,那么您需要的是一个接受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));