简体   繁体   English

我的通用方法有什么问题?

[英]What's wrong with my generic method?

the following generic method gives the compile error "Error 13 Value of type 'Distribution' cannot be converted to 't'" : 以下通用方法给出了编译错误“错误13类型'Distribution'的值不能转换为't'”:

Public Shared Function CreateObject(Of t)(ByVal ID As Integer) As t

        Dim TType As Type = GetType(t)

        If TType Is GetType(Distribution) Then
            Return CreateDistribution(ID)

        ElseIf TType Is GetType(Accrual) Then
            Return CreateAccrual(ID)

        End If


    End Function

CreateDistribution returns an object of type 'Distribution'. CreateDistribution返回“ Distribution”类型的对象。 I'm trying to get the method to perform an action based on the type of t supplied and then return an object of type t. 我正在尝试获取一种方法,该方法根据提供的t的类型执行操作,然后返回类型为t的对象。 What am I doing wrong? 我究竟做错了什么?

** Edit: I've commented out the entirety of Distribution other than the class declaration and still get the same error. **编辑:我已经注释掉除了类声明以外的所有Distribution,并且仍然收到相同的错误。

The compiler can't know ahead of time that the return type of CreateDistribution will match the type t, regardless of your if statement. 不管您是否使用if语句,编译器都无法提前知道CreateDistribution的返回类型将与类型t相匹配。 Does changing the line to this work? 将线路更改为此有效吗?

Return CType(CreateDistribution(ID), t)

Same for the second obviously. 显然,第二次相同。

You need to upcast to the return values to Object , then downcast to t . 您需要向上转换到Object的返回值,然后向下转换到t

For example: 例如:

Return CType(CType(CreateDistribution(ID), Object), t)

The two casts are necessary because the compiler doesn't know that t is Distribution . 这两个转换是必需的,因为编译器不知道tDistribution Therefore, it cannot allow you to cast from Distribution to t (which, as far as the compiler is concerned, might be Integer ). 因此,它不允许您从Distributiont (就编译器而言,它可能是Integer )。 However, once you upcast to Object , the second cast is fine, because Object can by definition be converted to t , no matter what type t is. 但是,一旦您转换为Object ,第二次转换就可以了,因为Object可以定义为t ,无论t是什么类型。
Pre-emptive snarky comment: Yes, I'm aware that that isn't true for pointers. 先发制人的狡猾评论:是的,我知道这对指针不是正确的。

Generic methods are resolved at compile-time, so the compiler needs to know up front what type T it is going to compile the function with. 泛型方法是在编译时解析的,因此编译器需要预先知道将使用哪种类型的T来编译函数。 Looks like you're looking to do a return based on runtime checking, in which case rather than a generic you'll want a method that returns an object that all of your possible returns inherit from. 看起来您希望基于运行时检查进行返回,在这种情况下,您将需要一个返回对象的方法,而不是泛型,该对象是所有可能的返回值所继承的对象。 The most basic one you could use would be object -- but obviously wherever you call it from you'd have to do some type checking. 您可以使用的最基本的对象是对象-但是显然无论您从哪里调用它,都必须进行某种类型检查。

I think you're always going to get an error, as at least one of your return statements will have a type mismatch. 我认为您总是会出错,因为至少有一个return语句将具有类型不匹配。 The compiler is almost certainly not smart enough to work out that only one of them can possibly be executed for a given t 几乎可以肯定,编译器不够聪明,无法解决在给定的t只能执行其中一个的问题。

Here is a more generic way to accomplish what you are trying to do: 这是完成您要尝试执行的操作的更通用的方法:

    Public Function CreateInstance(Of T)(ByVal ParamArray args() As Object) As T
        Dim obj As T

        If args IsNot Nothing AndAlso args.Length > 0 Then
            obj = CType(Activator.CreateInstance(GetType(T), args), T)
        Else
            obj = Activator.CreateInstance(Of T)()
        End If

        Return obj
    End Function

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM