4

I'm getting an AmbigiousMatchException for a function calling Type.GetMethod() even though everything looks pretty much correct.

public partial class IBaseEvent
{
    private Dictionary<int, Func<object[], object>> funcs = new Dictionary<int,Func<object[],object>>();
    private Dictionary<int, object[]> func_args = new Dictionary<int,object[]>();

    public void Execute()
    {
        int exp = 0;
        foreach(var func in funcs)
        {
            exp = func.GetHashCode();
            func.Value.DynamicInvoke(func_args[exp]);
        }
    }

    public void AddFunction(Type T, dynamic sFunc, params object[] parameters)
    {
        funcs.Add(T.GetHashCode(), new Func<object[],object>(T.GetMethod(sFunc)));
        func_args.Add(T.GetHashCode(), parameters);
    }
}

public class DummyEvent : IBaseEvent
{
    private string EventType = "DUMMY_EVENT";

    public DummyEvent()
    {
        object[] parm = new object[3];
        parm[0] = Logging.LOG_TYPE.DEBUG;
        parm[1] = "Hello World from DummyEvent! TypeCode: {0}";
        parm[2] = typeof(DummyEvent).GetType().GUID;

        AddFunction(typeof(Logging.LoggingFactory), "WriteToLog", parm);
    }
}

Errors on AddFunction(typeof(Logging.LoggingFactory), "WriteToLog", parm);

What am I doing wrong? and how can I correct this?

Matt Lima
  • 307
  • 2
  • 6

2 Answers2

2

Based on the error message, I suspect that you may already have a function WriteToLog in LoggingFactory or its inheritance chain.

competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • Yes there are two WriteToLog functions with different counts of parameters. One is public static int WriteToLog(LOG_TYPE pType, string Message) the other is public static int WriteToLog(LOG_TYPE pType, string pFormat, params object[] pParams – Matt Lima Nov 19 '11 at 02:46
  • The problem is that the second overload is essentially indistinguishable from the first unless you provide params. If you can, I would suggest adding another no-op param or changing the order of the first two params. – competent_tech Nov 19 '11 at 03:19
1

It seems like you are unnecessarily complicating stuff. Both the function and its argument are known whenever you are adding it to the list. Have you considering using anonymous functions like so. As an example I have wrapped the this object.. the string argument in this example. DynamicInvoke will be considerably slower as well.

Also two different Types can return the same GetHashCode which depending on your particular needs may or may not matter.

public partial class IBaseEvent
    {
        private Dictionary<int, Action> funcs = new Dictionary<int, Action>();

        public void Execute()
        {
            foreach (var func in funcs.Values)
            {
                func();
            }
        }

        public void AddFunction(Type t, Action ff)
        {
            funcs.Add(t.GetHashCode(), ff);
        }
    }

    public class DummyEvent : IBaseEvent
    {
        private string EventType = "DUMMY_EVENT";

        private void DoSomething(string x)
        {
            Console.WriteLine(x);
        }

        public DummyEvent()
        {
            Action temp = () =>
                {
                    DoSomething("Hello World from DummyEvent! TypeCode");
                };

            AddFunction(typeof(Logging), temp);
        }
    }

If type is strictly not needed you can further simply it like so

 public partial class IBaseEvent
{
    public Action MyAction;


    public void Execute()
    {
        MyAction();
    }

    public void AddFunction(Action ff)
    {
        MyAction += ff;
    }
}
parapura rajkumar
  • 24,045
  • 1
  • 55
  • 85
  • I'm just using the hash-code as a temporary storage. After the function gets executed its generally deleted from the processing queue, thats why the hash-code also doesn't really matter much. – Matt Lima Nov 19 '11 at 02:45
  • I have edited my answer to further simplify it if Type map is not strictly needed – parapura rajkumar Nov 19 '11 at 02:53