.NET Generics,按名称拉取对象成员值

时间:2014-08-01 18:27:56

标签: .net vb.net unit-testing reflection assert

我将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

将执行业务逻辑的Generic 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(&#34; asdf&#34;)和actualFoo(&#34; qwer&#34;)的律师资格成员进行比较。我在FieldInfo,PropertyInfo或MemberInfo中找不到任何值,这些值允许我按名称获取分配给该属性的值。

2 个答案:

答案 0 :(得分:1)

我不明白为什么在这种情况下不会这样做:

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

答案 1 :(得分:1)

因为结构的性质和正在测试的内容都是已知的,所以我使用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