Как получить общее определение типа для типа CRTP - PullRequest
5 голосов
/ 22 июля 2011

С учетом следующего CRTP введите C #:

public abstract class DataProviderBase<TProvider>
    where TProvider : DataProviderBase<TProvider> { }

Как бы я получил определение его общего типа в F #?

let typeDef = typedefof<DataProviderBase<_>>

выдает ошибку:

Несоответствие ограничения типа при применении типа по умолчанию DataProviderBase <'a>' для переменной вывода типа. Результирующий тип будет бесконечным при объединении '' a 'и' DataProviderBase <'a>'. Рассмотрите возможность добавления дополнительных ограничений типа

В C # это будет:

var typeDef = typeof(DataProviderBase<>);

UPDATE

Я нашел обходной путь:

[<AbstractClass>]
type DummyProvider() =
  inherit DataProviderBase<DummyProvider>()

let typeDef = typeof<DummyProvider>.BaseType.GetGenericTypeDefinition()

Есть ли другой способ сделать это, без дополнительного типа?

1 Ответ

4 голосов
/ 22 июля 2011

Я думаю, что это действительно очень хороший вопрос.Я не нашел лучшего обходного пути для этого.Вы можете немного упростить ваш обходной путь, используя typedefof, например:

let typeDef = typedefof<DataProviderBase<DummyProvider>>

ТЕХНИЧЕСКИЕ ХАРАКТЕРИСТИКИ

Проблема в том, что F # * typedefof<'T> - просто обычная функцияэто принимает аргумент типа (в отличие от typeof в C #, который является оператором).Чтобы вызвать его, вам нужно присвоить ему фактический тип, а затем функция вызовет GetGenericTypeDefinition под обложкой.

Причина, по которой typedefof<option<_>> работает, заключается в том, что F # задает по умолчанию введите в качестве аргумента (в данном случае obj).В общем, F # выбирает менее конкретный тип, который соответствует ограничениям.В вашем случае:

DataProviderBase<_> станет DataProviderBase<DataProviderBase<_>> и т. Д.

Если вы не определите новый тип (как в вашем обходном пути), конкретный тип * отсутствует1025 *, который можно использовать в качестве аргумента типа typedefof<...>.В этом случае механизм по умолчанию просто не работает ...

...