I am passing in 2 generic objects and a string into a function and I would like to find the property of the objects that match the string and compare their values.
Here is a sample model:
Public Structure Foo
Public Bar As String
Public Nan As String
Public Tucket As String
End Structure
and the calling class:
<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
The Generic Assert class that will be doing the business logic
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
The expected outcome will be that the Bar member of expectedFoo
("asdf") and actualFoo
("qwer") would be compared. I cannot find any value in FieldInfo, PropertyInfo or MemberInfo that will allow me to get the value assigned to that property by name.
Because both the nature of the structure and the what is being tested for is known, I used FieldInfo objects as the most straight forward way to get the field values.
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