Где «неопределенный тип»? - PullRequest
2 голосов
/ 04 мая 2010

Я определяю следующее расширение типа:

type System.Reflection.MemberInfo with
    member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') =
        match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with
        | true, null -> invalidOp (sprintf "Missing required attribute: %s" typeof<'T>.FullName)
        | _, attr -> attr :> 'T

Последнее выражение соответствия (attr :> 'T) выдает ошибку:

Статическое приведение от атрибута к 'T имеет неопределенный тип, основанный на информации, предшествующей этой точке программы. Статические принуждения не допускаются на некоторых типах. Необходимы дополнительные аннотации типов.

Я пытался аннотировать возвращаемый тип функции, но получил тот же результат. Я не хотел бы изменить это на динамический бросок. Есть ли способ заставить статическое приведение работать?

Ответы [ 3 ]

3 голосов
/ 04 мая 2010

Это должен быть динамический состав, верно? У вас есть объект со статическим типом System.Attribute, и вы хотите уменьшить его до фактического конкретного типа.

open System
type System.Reflection.MemberInfo with 
  member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') =  // '
    match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with 
    | true, null -> invalidOp (
        sprintf "Missing required attribute: %s" typeof<'T>.FullName)  // '
    | _, attr -> attr :?> 'T 
1 голос
/ 05 мая 2010

Чтобы прояснить смысл сообщения об ошибке - компилятор делает различие между статическим приведением :> (которое всегда безопасно, например приведение с Random до Object) и динамическим приведением :?> (которое может завершиться ошибкой ).

В вашем случае вам нужно использовать динамическое приведение. Вот что означает компилятор:

  • В нем говорится, что "Статическое приведение от атрибута к 'T имеет неопределенный тип" . Это означает, что он не знает (во время компиляции), какой фактический тип используется вместо универсального параметра 'T.

  • В результате компилятор не может проверить, всегда ли будет успешно выполнено преобразование из Attribute в 'T (что требуется в случае статических приведения). Если, например, компилятор определил, что тип 'T будет всегда Object, тогда использование статического приведения будет допустимым.

0 голосов
/ 04 мая 2010

Исправленный код, на случай, если он кому-нибудь полезен (код Брайана тоже правильный ... Я просто предпочитаю аннотацию типа в подписи):

type System.Reflection.MemberInfo with
    member x.GetAttribute<'T when 'T :> Attribute>(required, inherit') : 'T =
        match required, Attribute.GetCustomAttribute(x, typeof<'T>, inherit') with
        | true, null -> invalidOp (sprintf "Missing required attribute: %s" typeof<'T>.FullName)
        | _, attr -> downcast attr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...