C# 调用需要在VB.NET或C中键入为基类的派生类实例的方法#

C# 调用需要在VB.NET或C中键入为基类的派生类实例的方法#,c#,.net,vb.net,class,downcast,C#,.net,Vb.net,Class,Downcast,我有两个物体——“宇宙飞船”和“行星”来自一个基本的“Obj”。我定义了几个类——圆、三角形、矩形等,它们都继承自一个“Shape”类 出于碰撞检测目的,我想给Obj一个“形状”: 所以在“太空船”里我可以: 在《星球》中,我可以: 我有一个方法(多次重载)检查不同形状之间的碰撞,例如: public shared overloads function intersects(byval circle1 as circle, byval circle2 as circle) as boolean

我有两个物体——“宇宙飞船”和“行星”来自一个基本的“Obj”。我定义了几个类——圆、三角形、矩形等,它们都继承自一个“Shape”类

出于碰撞检测目的,我想给Obj一个“形状”:

所以在“太空船”里我可以:

在《星球》中,我可以:

我有一个方法(多次重载)检查不同形状之间的碰撞,例如:

public shared overloads function intersects(byval circle1 as circle, byval circle2 as circle) as boolean
dim A as new circle(blah, blah)
dim B as new triangle(blah, blah)
return intersects(A,B)

当我使用派生类调用函数时,这种方法很好,例如:

public shared overloads function intersects(byval circle1 as circle, byval circle2 as circle) as boolean
dim A as new circle(blah, blah)
dim B as new triangle(blah, blah)
return intersects(A,B)
但是当我使用MyShape调用它时,我得到了一个错误,因为该方法被传递了一个“Shape”(而不是派生类型),该方法没有重载

我可以通过以下方式解决这个问题:

Public Function Translate(byval MyShape1 as Shape, byval MyShape2 as Shape )as boolean
if shape1.gettype = gettype(circle) and shape2.gettype=gettype(circle) then ''//do circle-circle detection
if shape1.gettype = gettype(triangle) and shape2.gettype=gettype(circle) then ''//do triangle-circle detection
End Function

但这看起来很混乱。有更好的方法吗?

一种解决方法是将
MyActualFunction
作为类成员插入

形状:

Public MustOverride Function MyActualFunction()
End Function
在圆和三角形中:

Public Overrides Function MyActualFunction()
End Function
那就这样说吧:

MyShape.MyActualFunction()

这将知道要调用哪个函数。

多态性无法帮助您实现这一点,因此您必须使用
Shape
类型的两个参数创建一个通用方法,然后在其中区分它们:

Public Function DoCollide(ByRef shape1 As Shape, ByRef shape2 As Shape) As Boolean
    If TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Circle) IsNot Nothing Then
        Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Circle))
    ElseIf TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Triangle) IsNot Nothing Then
        Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Triangle))
    Else
        Return False
    End If
End Function
我将把这个函数与所有在自己的类中执行实际碰撞检测的专用实现放在一起
CollisionDetector

Public Class CollisionDetector

    Public Function DoCollide(ByRef shape1 As Shape, ByRef shape2 As Shape) As Boolean
        If TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Circle) IsNot Nothing Then
            Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Circle))
        ElseIf TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Triangle) IsNot Nothing Then
            Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Triangle))
        Else
            Return False
        End If
    End Function

    Public Function DoCollide(ByRef circle1 As Circle, ByRef circle2 As Circle) As Boolean
        Return True
    End Function

    Public Function DoCollide(ByRef circle As Circle, ByRef triangle As Triangle) As Boolean
        Return True
    End Function

End Class

更改方法参数时,它应该采用形状对象,而不是具体的子对象(C#)#2很抱歉您在理解问题时遇到困难。我实际上认为“子对象”和“派生类”或多或少是一回事。也许你能解释一下两者之间的区别,你认为我应该在这个特殊情况下使用它们?我只创建了“Shape”类来将形状分组,这样我就可以使用
Dim MyShape as Shape
来覆盖所有可能的形状。@JesseJames我实际上使用了一个重载方法,它根据传递给它的两个形状做不同的事情。例如,如果我传递一个圆和一个三角形,它实际上会调用与传递两个圆不同的方法。对不起,我只是想简化一下情况,让问题更容易理解。@Gravitate我倾向于将子对象理解为一种关联。派生类是继承基类的类。@MatíasFidemraizer有什么功能上的区别吗?“子对象”可以访问其“父对象”属性,就像派生类可以访问其基本属性一样,不是吗?我想您可以使用“Parent.child”来引用子级,但不能使用“Base.Derived”来引用子级。必须有更根本的区别,那就是。。。我将不得不问无所不知的谷歌:)嗨,谢谢你的输入。这将解决我的问题,但是,我简化了一些情况,使其更容易理解。我实际使用的方法是重载的,并接受2个“形状”。所以,如果我通过(圆,圆),它会做一些不同的事情,如果我通过(圆,三角形)。对不起,我在问题中没有说清楚。我现在要更新它。这个方法到底做什么?它是组合形状还是在每个形状上做一件事?它是一个碰撞检测库(几乎)。我给每个物体指定一个形状(比如说,一个三角形代表宇宙飞船,一个圆形代表行星)。然后将这两个形状传递给该方法。然后检查形状是否相交。显然,检查交点的方法会因传递给它的形状类型而异。我只希望“形状”存储在我所有对象的同一个变量中。我走错方向了吗?因为我觉得我是,但是想不出其他的选择。好的,我刚刚更新了这个问题。我希望我现在所做的有意义。谢谢,但我得到一个错误-圆圈是一种类型,不能用作表达式。。。这就是为什么在我的问题中,我比较了Myshape.GetType和GetType(Circle),这两种方法都有效。。。“但这似乎不是正确的方法。”万有引力对此表示抱歉。我对VB不是很熟练,这就是为什么我的代码受到C的影响。我现在修复了代码并扩展了解释。谢谢,但这与我在问题中建议的基本相同,只是用不同的方式检查了类型。我希望有一个更好的方法,但我不确定有没有。我想我需要继续做下去,或者做很多重组,尽管我不知道如何做。顺便说一句,你看过这个吗?它非常适合在vb和c#之间进行转换。@Gravitate我不知道有什么更好的方法可以实现这一点。如果你能找到它,就把它贴在这里,这样别人就能看到它。谢谢你的链接:我不知道,它可能会派上用场。
Public Function DoCollide(ByRef shape1 As Shape, ByRef shape2 As Shape) As Boolean
    If TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Circle) IsNot Nothing Then
        Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Circle))
    ElseIf TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Triangle) IsNot Nothing Then
        Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Triangle))
    Else
        Return False
    End If
End Function
Public Class CollisionDetector

    Public Function DoCollide(ByRef shape1 As Shape, ByRef shape2 As Shape) As Boolean
        If TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Circle) IsNot Nothing Then
            Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Circle))
        ElseIf TryCast(shape1, Circle) IsNot Nothing And TryCast(shape2, Triangle) IsNot Nothing Then
            Return DoCollide(TryCast(shape1, Circle), TryCast(shape2, Triangle))
        Else
            Return False
        End If
    End Function

    Public Function DoCollide(ByRef circle1 As Circle, ByRef circle2 As Circle) As Boolean
        Return True
    End Function

    Public Function DoCollide(ByRef circle As Circle, ByRef triangle As Triangle) As Boolean
        Return True
    End Function

End Class