Почему F #, использующий Xunit, требует информацию о типе при утверждении равенства в строках - PullRequest
2 голосов
/ 25 февраля 2012

Я использую F # и Xunit.(Я относительно новичок в обоих случаях)

Я обнаружил, что когда я использую Assert.Equal () Xunit, мне нужно указать "<string>", когда сравниваемые типы являются строковыми.

Например, этот прогон и компилирует:

[<Fact>]
let Test_XunitStringAssertion() =
    let s1 = "Stuff"
    Assert.Equal<string>("Stuff",s1)

Мой вопрос: почему я не могу удалить "<string>" и просто вместо этого утверждать "Assert.Equal("Stuff",s1)"?

Этомне кажется, что компилятор знает типы обоих аргументов, так почему суета?

Вот ошибки, возвращаемые при компиляции Assert.Equal("Stuff",s1):

error FS0041: A unique overload for method 'Equal' could not be determined based on type information prior to this program point. The available overloads are shown below (or in the Error List window). A type annotation may be needed.
error FS0041: Possible overload: 'Assert.Equal<'T>(expected: 'T, actual: 'T) : unit'.
error FS0041: Possible overload: 'Assert.Equal<'T>(expected: seq<'T>, actual: seq<'T>) : unit'.
error FS0041: Possible overload: 'Assert.Equal<'T>(expected: 'T, actual: 'T, comparer: System.Collections.Generic.IEqualityComparer<'T>) : unit'.
error FS0041: Possible overload: 'Assert.Equal(expected: float, actual: float, precision: int) : unit'.
error FS0041: Possible overload: 'Assert.Equal(expected: decimal, actual: decimal, precision: int) : unit'.
error FS0041: Possible overload: 'Assert.Equal<'T>(expected: seq<'T>, actual: seq<'T>, comparer: System.Collections.Generic.IEqualityComparer<'T>) : unit'.

Ответы [ 2 ]

4 голосов
/ 26 февраля 2012

Ваш пример с удаленным <string> запускается без ошибок для меня, как я и ожидал (хотя string :> seq<char>, как указывает @Ramon Snir, алгоритм разрешения перегрузки разрешает неоднозначность, распознавая, что поставляемые типы string ""ближе к string, чем seq<char>).

[<Fact>]
let Test_XunitStringAssertion() =
    let s1 = "Stuff"
    Assert.Equal("Stuff",s1)

Полагаю, что предоставленный вами пример не совсем совпадает с реальным кодом, который вызывает у вас проблемы.Возможно, s1 в вашем реальном коде на самом деле не является string (или, по крайней мере, компилятор не знает, что это так).

4 голосов
/ 25 февраля 2012

Это потому, что string может соответствовать как первой, так и второй перегрузкам (помните: string :> seq<char>).

...