0

I'm working on a personal project to build a Truth Table Generator, with an emphasis on collecting/cementing what I'm learning about logical equivalence.

As such, I'm trying to write it in such a way that it takes a C# Function as an argument. I'll turn it into a "build a compiler project" later, but for now I want to learn more about delegates, metaprogramming, and have fun with logical equivalence while at it.

So, what I'm trying to figure out is how syntactically I would define a Delegate that takes 1 to N boolean arguments, such that I avoid violating DRY like this...

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...);

...and I don't believe the below will do it, as "ListOnlyFunc" takes a list of type boolean as a single argument--when what I want is a delegate that can accept a boolean function with two boolean arguments, or a function with 1200 boolean arguments.

public delegate bool ListOnlyFunc(bool[] args); // Nope!

Part of the reason I want to avoid that latter is that I want to be able to extract the argument names from the function, as well (instead of displaying generic indexed arguments). For instance, if I run the below I should see "foo, baz, turkey" in the output window; I don't want to simply get the count of the number of arguments and output an index ("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();

    }
}

If you have any tips on how I could approach this (or if it is even possible), advice would be greatly appreciated. :)

Thanks,

Chris

Community
  • 1
  • 1
Chris
  • 71
  • 5
  • Consider using `MethodInfo`, which allows fetching parameter names and also invoking the function, if you provide an array with the correct number of elements matching the expected number of parameters. – Ben Voigt Jan 08 '16 at 05:01
  • In my mind the code you provided (`MyFunc`) doesn't logically fit in with the list of delegates you provided. I think you need to flesh out your code a bit more and show how it relates to the delegates. – Enigmativity Jan 08 '16 at 05:19

3 Answers3

0

you can define param method delegate like this

 public delegate bool SumParameters(params bool[] values)

if you want name of argument than you can make use of dictionary , this solution already suggested by @Rob

 public delegate bool SumParameters(Dictionary<string,bool> values)
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • This still has the issue that he needs the parameter names (`I don't want to simply get the count of the number of arguments and output an index ("1, 2, 3").`) – Rob Jan 08 '16 at 05:04
0

Since you want argument names, it gets a bit messy. Depending on what you want to do, you can write something like this:

public void MyFunc(bool? argOne = null, 
              bool? argTwo = null,
              bool? argThree = null,
              bool? argFour = null,
              bool? argFive = null)
{

}

And you can call it like this:

MyFunc(true);
MyFunc(true, false);
MyFunc(true, false, true);
MyFunc(true, false, true, false);

However, this raises some complications. Is this valid, for example?

MyFunc(null, true)

Here we've only supplied argTwo, but it might make sense that you must provide all previous arguments as well (ie. it's not valid to skip an argument).

Alternatively, you can do something like this:

public void MyFunc(Dictionary<string, bool> args)
{

}

And call it like this:

 MyFunc(new Dictionary<string, bool> { { "arg1", true }, {"arg2", true } });
Rob
  • 26,989
  • 16
  • 82
  • 98
0

If all you want to do is get some information about the method then what you need is a method that accepts a Delegate as a parameter:

public static string MethodSignature(Delegate del) => del.Method.ToString();

The downside to this is that a method is not a Delegate (or a delegate) so you'll have to cast to Func<...>, Action<...> or some other suitable delegate type at the time of the call like this:

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

Of course if you already have a delegate you don't need the cast.

Either way, once you have a delegate the parameter names are available:

public static string ParameterNames(Delegate del) => 
    string.Join(", ", del.Method.GetParameters().Select(p => p.Name));
Corey
  • 15,524
  • 2
  • 35
  • 68