我正在尝试比较两种方法的哈希输出,看看它们是否相等。
到目前为止,这是我的代码:
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));
}
我收到错误消息:“无法从用法中推断出方法的类型参数。尝试显式指定类型参数。”我在做什么错了?
答案 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);
}
断言可以编译并起作用。 尽管现在要花费您的性能。