我将首先展示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
的访问级别更改为Public
时,代码会按预期工作。
奇怪的是,当我在VS 2015 上尝试上述代码 的C#等价物时,它运行得很好, 但是 在.NET Fiddler上,它没有。
.NET Fiddler上的Here's the C# example,我得到的内容与VB.NET相同。
那么,有什么我做错了吗?
答案 0 :(得分:0)
我无法回答这个问题的原因,但我可以提供解决方法。
创建Interface
并在BaseClass
中实施。然后,不是将Casted
声明为Object
,而是将其声明为接口,它将使用与之前相同的访问修饰符正确公开所需的属性。
以下完整示例。
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