“尝试显式指定类型参数”中哈希比较结果的比较结果

时间:2019-06-17 10:15:53

标签: c# delegates

我正在尝试比较两种方法的哈希输出,看看它们是否相等。

到目前为止,这是我的代码:

Helper.cs:

public static bool HashIsTheSame<TResult>(Func<object[], TResult> method1, Func<object[], TResult> method2, params object[] args)
{
    TResult method1Result = method1(args);
    TResult method2Result = method2(args);

    return GetHashString(method1Result).Equals(GetHashString(method2Result));
}

private static string GetHashString(object inputString)
{
    StringBuilder sb = new StringBuilder();
    foreach (byte b in GetHash(inputString.ToString()))
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}

private static byte[] GetHash(string inputString)
{
    HashAlgorithm algorithm = SHA256.Create();
    return algorithm.ComputeHash(Encoding.UTF8.GetBytes(inputString));
}

repo.cs:

public int TestMethod1(int value1, int value2)
{
    return value1 + value2;
}
public int TestMethod2(int value1, int value2)
{
   return value1 * value2;
}

当我这样称呼它时:

Test.cs:

public void HashTest()
{
    var value1 = 1;
    var value2 = 2;
    object[] args = {value1, value2};
    Assert.IsFalse(TestHelper.HashIsTheSame(repo.TestMethod1(value1, value2), repo.TestMethod2(value1, value2), args));
}

我收到错误消息:“无法从用法中推断出方法的类型参数。尝试显式指定类型参数。”我在做什么错了?

1 个答案:

答案 0 :(得分:1)

Func<object[], int>Func<int, int, int>不兼容。由于Func<params object[], TResult>是不可能的,因此唯一的方法是定义多个这样的重载:

static class TestHelper
{
    public static bool HashIsTheSame<TResult>(Func<TResult> method1,
        Func<TResult> method2) =>
        GetHashString(method1()).Equals(method2());

    public static bool HashIsTheSame<T, TResult>(Func<T, TResult> method1,
        Func<T, TResult> method2,
        T arg) =>
        GetHashString(method1(arg)).Equals(method2(arg));

    public static bool HashIsTheSame<T1, T2, TResult>(Func<T1, T2, TResult> method1,
        Func<T1, T2, TResult> method2,
        T1 arg1, T2 arg2) =>
        GetHashString(method1(arg1, arg2)).Equals(method2(arg1, arg2));

    public static bool HashIsTheSame<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> method1,
        Func<T1, T2, T3, TResult> method2,
        T1 arg1, T2 arg2, T3 arg3) =>
        GetHashString(method1(arg1, arg2, arg3)).Equals(method2(arg1, arg2, arg3));

    public static bool HashIsTheSame<T1, T2, T3, T4, TResult>(Func<T1, T2, T3, T4, TResult> method1,
        Func<T1, T2, T3, T4, TResult> method2,
        T1 arg1, T2 arg2, T3 arg3, T4 arg4) =>
        GetHashString(method1(arg1, arg2, arg3, arg4)).Equals(method2(arg1, arg2, arg3, arg4));

    public static bool HashIsTheSame<T1, T2, T3, T4, T5, TResult>(Func<T1, T2, T3, T4, T5, TResult> method1,
        Func<T1, T2, T3, T4, T5, TResult> method2,
        T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) =>
        GetHashString(method1(arg1, arg2, arg3, arg4, arg5)).Equals(method2(arg1, arg2, arg3, arg4, arg5));

    // etc. Depends on what number of arguments you believe to make sense.
}

使用这种方法可以编译:

var repo = new Repo();
Assert.IsFalse(TestHelper.HashIsTheSame(repo.TestMethod1, repo.TestMethod2, 1, 2));

解决方案2:

即使使用显式参数,您的代码也不会编译:

Assert.IsFalse(TestHelper.HashIsTheSame(new Func<object[], int>(repo.TestMethod1), new Func<object[], int>(repo.TestMethod2), 1, 2));
  

No overload for 'TestMethod1' matches delegate 'Func<object[], int>'

     

No overload for 'TestMethod2' matches delegate 'Func<object[], int>'

如果将其更改为:

Assert.IsFalse(TestHelper.HashIsTheSame(new Func<int, int, int>(repo.TestMethod1), new Func<int, int, int>(repo.TestMethod2), 1, 2));

您遇到了原始错误:

  

The type arguments for method 'TestHelper.HashIsTheSame<TResult>(Func<object[], TResult>, Func<object[], TResult>, params object[])' cannot be inferred from the usage. Try specifying the type arguments explicitly.

但是,如果您更改了HashIsTheSame

public static bool HashIsTheSame(MulticastDelegate method1, MulticastDelegate method2, params object[] args)
{
    object method1Result = method1.DynamicInvoke(args);
    object method2Result = method2.DynamicInvoke(args);

    return GetHashString(method1Result).Equals(method2Result);
}

断言可以编译并起作用。 尽管现在要花费您的性能。