Я передаю 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

Ожидаемый результат будет заключаться в том, что будет сравниваться член Bar expectedFoo ("asdf") и actualFoo ("qwer"). Я не могу найти никакого значения в FieldInfo, PropertyInfo или MemberInfo, которое позволило бы мне получить значение, присвоенное этому свойству по имени.

0
theB3RV 1 Авг 2014 в 22:27
.GetValue() этого не сделает?
 – 
John Alexiou
1 Авг 2014 в 22:45
expectedId.GetValue() ожидает, что я передам объект, но expectId — это объект Bar, поэтому мне нечего передавать. expected не имеет .GetValue()
 – 
theB3RV
1 Авг 2014 в 22:50
expectedProperties.GetValue(), если вы установили, что он называется identifier. Вы передаете экземпляр expectedFoo
 – 
John Alexiou
1 Авг 2014 в 22:56
expectedProperties имеет тип MemberInfo(). expectedProperties.GetValue(expectedId) имеет ошибку компилятора "Неверные типы аргументов. Кандидаты - Integer или Long.
 – 
theB3RV
1 Авг 2014 в 23:00
3
Похоже, вы пытаетесь написать многоразовые модульные тесты для сравнения объектов; вы можете взглянуть на идиомы идиомы и подпроекты SemanticComparison, а также Albedo.
 – 
Mark Seemann
4 Авг 2014 в 19:47

2 ответа

Лучший ответ

Поскольку известны как природа структуры, так и то, что проверяется, я использовал объекты 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
1
Predrag Djukic 8 Авг 2014 в 21:19

Я не понимаю, почему в данном случае этого не будет:

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
John Alexiou 1 Авг 2014 в 23:31
Первый аргумент GetValue() может быть только целым или длинным в соответствии с моим компилятором. Где expected имеет тип t (или Foo во время выполнения)
 – 
theB3RV
1 Авг 2014 в 23:41
Кроме того, ожидаемое имеет тип Foo, ожидаемое_проп — это список свойств Foo, поэтому expected_prop.GetValue(expected) не имеет смысла...
 – 
theB3RV
1 Авг 2014 в 23:45