我正在传递2个通用对象和一个字符串到一个函数中,我想找到与字符串匹配的对象的属性并比较它们的值。
下面是一个示例模型:
Public Structure Foo
Public Bar As String
Public Nan As String
Public Tucket As String
End Structure
和调用类:
<TestMethod()>
Public Sub TestEquality_Class_Pass_Identifier()
_tester = new GeneralAssert
Dim expectedFoo = New Foo With {.Bar = "asdf", .Nan = "zxcv", .Tucket = "qwer"}
Dim actualFoo = New Foo With {.Bar = "qwer", .Nan = "zxcv", .Tucket = "qwer"}
_tester.TestEquality(expectedFoo, actualFoo, "Bar")
End Sub
将执行业务逻辑的泛型Assert类
Public Class GenericAssert
Public Sub TestEquality(Of t)(expected As t, actual As t, Optional identifier As String = Nothing)
Dim expectedType = expected.GetType(), actualType = actual.GetType()
Assert.AreEqual(expectedType, actualType)
If (Not identifier Is Nothing) Then
Dim expectedProperty = expectedType.GetMember(identifier).FirstOrDefault()
Dim actualProperty = actualType.GetMember(identifier).FirstOrDefault()
TestEquality(*WhatHere1*, *WhatHere2*)
End If
End Sub
End Class
预期结果将是比较expectedFoo
("asdf")和actualFoo
("qwer")的Bar成员。我在FieldInfo, PropertyInfo或MemberInfo中找不到任何值,这将允许我通过名称获得分配给该属性的值。
因为结构的性质和要测试的内容都是已知的,所以我使用FieldInfo对象作为获取字段值的最直接的方法。
Public Sub TestEquality(Of t)(expected As t, actual As t, Optional identifier As String = Nothing)
Dim expectedType = expected.GetType()
Dim actualType = actual.GetType()
Assert.AreEqual(expectedType, actualType)
If (identifier IsNot Nothing) Then
Dim expectedField As FieldInfo = expectedType.GetField(identifier, BindingFlags.IgnoreCase Or BindingFlags.Public Or BindingFlags.Instance)
Dim actualField As FieldInfo = actualType.GetField(identifier, BindingFlags.IgnoreCase Or BindingFlags.Public Or BindingFlags.Instance)
Assert.AreEqual(expectedField.GetValue(expected), actualField.GetValue(actual))
End If
End Sub
我不明白为什么在这种情况下不能这样做:
Public Sub AssertEquality(Of T)(ByVal expected As T, ByVal actual As T, identifier As String)
Dim expected_prop = expected.GetType().GetProperty(identifier, BindingFlags.Instance + BindingFlags.Public)
Dim actual_prop = actual.GetType().GetProperty(identifier, BindingFlags.Instance + BindingFlags.Public)
Dim expected_value = expected_prop.GetValue(expected, Nothing)
Dim actual_value = actual_prop.GetValue(actual, Nothing)
Assert.AreEqual(expected_value, acutal_value)
End Sub
Sub Main()
Dim expectedFoo = New Foo With {.Bar = "asdf", .Nan = "zxcv", .Tucket = "qwer"}
Dim actualFoo = New Foo With {.Bar = "qwer", .Nan = "zxcv", .Tucket = "qwer"}
AssertEquality(expectedFoo, actualFoo, "Bar")
End Sub