2

我将首先展示 VB.NET 代码,因为它的 C# 等价物的行为更加令人困惑(见下文)

考虑以下三个类:

Public Class BaseClass
    Private Shared Rand As New Random
    Public Shared Function CreateDerived() As BaseClass
        Return If(Rand.Next(1, 3) = 1, New DerivedClass1(), New DerivedClass2())
    End Function
End Class

Public Class DerivedClass1
    Inherits BaseClass

    Sub New()
        MyProperty = 1
    End Sub

    Friend Property MyProperty As Integer
End Class

Public Class DerivedClass2
    Inherits BaseClass

    Sub New()
        MyProperty = 2
    End Sub

    Friend Property MyProperty As Integer
End Class

现在,当我尝试做这样的事情时:

Sub Foo()
    Dim targetClass As BaseClass = BaseClass.CreateDerived()

    Dim Casted
    If TypeOf (targetClass) Is DerivedClass1 Then
        Casted = DirectCast(targetClass, DerivedClass1)
    ElseIf TypeOf (targetClass) Is DerivedClass2 Then
        Casted = DirectCast(targetClass, DerivedClass2)
    Else
        Exit Sub
    End If

    Console.WriteLine(Casted.MyProperty) 'Throws an exception.
End Sub

我似乎无法访问MyProperty,并且收到以下异常:

未找到类型“DerivedClass1”的公共成员“MyProperty”。

MyProperty因此,当我更改to的访问级别时Public,代码按预期工作。

奇怪的是,当我在 VS 2015 上尝试上述代码的 C# 等效项时,它工作得很好,在 .NET Fiddler 上却不行。

这是 .NET Fiddler 上的 C# 示例,我在其中得到与 VB.NET 相同的行为。

那么,我做错了什么吗?

4

1 回答 1

0

我无法回答这个问题的原因,但我可以提供一个解决方法。

创建一个Interface并在您的BaseClass. 然后,您可以将其声明为接口,而不是声明CastedObject,这将正确地公开您想要的属性,并使用与以前相同的访问修饰符。

下面的完整示例。

Sub Foo()
    Dim targetClass As BaseClass = BaseClass.CreateDerived()

    Dim Casted As Interf
    If TypeOf (targetClass) Is DerivedClass1 Then
        Casted = DirectCast(targetClass, DerivedClass1)
    ElseIf TypeOf (targetClass) Is DerivedClass2 Then
        Casted = DirectCast(targetClass, DerivedClass2)
    Else
        Exit Sub
    End If

    Console.WriteLine(Casted.MyProperty) 'Throws an exception.
End Sub

Friend Interface Interf
    Property MyProperty As Integer
End Interface

Public Class BaseClass
    Implements Interf

    Private Shared Rand As New Random

    Friend Overridable Property MyProperty As Integer Implements Interf.MyProperty

    Public Shared Function CreateDerived() As BaseClass
        Return If(Rand.Next(1, 3) = 1, New DerivedClass1(), New DerivedClass2())
    End Function
End Class

Public Class DerivedClass1
    Inherits BaseClass

    Sub New()
        MyProperty = 1
    End Sub

    Friend Overrides Property MyProperty As Integer
End Class

Public Class DerivedClass2
    Inherits BaseClass

    Sub New()
        MyProperty = 2
    End Sub

    Friend Overrides Property MyProperty As Integer
End Class
于 2017-11-10T09:52:00.677 回答