2017-08-18 73 views
0

我有以下类设置,我不明白为什么它不会编译。如何使用泛型覆盖派生类中的属性

我得到的“公共覆盖物业˚F作为T”

  • “公共覆盖物业˚F作为T”下面的错误,因为他们的返回类型不同,无法重写“公众可重写属性˚F作为X”。
  • 这混淆了我,因为我受限吨至从十衍生

有人能解释我是如何实现这一目标?最后,我需要有A类和B类,其中B从A继承。其中A具有类型X的可重写属性F,并且B使用从X派生的类型重写F.任何建议都将被赞赏。如果这不能完成,我有兴趣知道为什么(限制.NET?)以及我应该如何去做。

Public Class X 
End Class 

Public Class Y 
    Inherits X 
End Class 

Public Class A 
    Public Overridable Property F As X 
End Class 

Public Class A(Of T As X) 
    Inherits A 
    Public Overrides Property F As T 
End Class 

Public Class B 
    Inherits A(Of Y) 
    Public Overrides Property F As Y 
End Class 

谢谢!

+0

为什么你需要这个,如果你将它限制为'X'或它的任何后代呢? –

+0

@VisualVincent - 我没有在这些类中包含可重写的函数。他们每个人都根据他们所在的类来做特定的工作。基本上,类B基于BF中的值具有特定于一个用例的业务逻辑,而对于所有其他实例则回退到A并按定义完成工作在A. –

+0

即使对SO样本也是“好名字”) – Fabio

回答

0

我终于找到了一个解决方案,使用Shadows关键字后我做了什么。

Imports System 

Public Module Module1 
    Public Sub Main() 
     Dim a As New A() 
     Dim b As New B() 

     a.F = New X() 
     b.F = New Y() 

     Dim c As New Container() 
     c.Value = a 

     Console.WriteLine(c)   

     c.Value = b 

     Console.WriteLine(c)   
    End Sub 
End Module 

Public Class Container 
    Public Value As A 
    Public Overrides Function ToString() AS String 
     Return Value.ToString() 
    End Function 
End Class 

Public Class X 
    Public Overrides Function ToString() AS String 
     Return "X" 
    End Function 
End Class 

Public Class Y 
    Inherits X 
    Public Overrides Function ToString() AS String 
     Return "Y" 
    End Function 
End Class 


Public Class A 
    Public Overridable Property F As X 
    Public Overrides Function ToString() AS String 
     Return "A" + F.ToString() 
    End Function 
End Class 

Public Class B 
    Inherits A 
    Public Shadows Property F As Y 
    Public Overrides Function ToString() AS String 
     Return "B" + F.ToString() 
    End Function 
End Class 
1

新答复。正如你所看到的,我不认为这是可能的(正如你所要求的那样),即B overrides F with a type that is derived from X

但是你可以在B中的私有字段持有Y和通过F.揭露它,那么你就需要投F至y以访问任何功能Ÿ提供了X.这可以在不改变A.

完成
Public Class X 
    Public Overridable Function Z() As String 
     Return "X" 
    End Function 
End Class 

Public Class Y 
    Inherits X 
    Public Overrides Function Z() As String 
     Return "Y" 
    End Function 
    Public Function Foo() As String 
     Return "Bar" 
    End Function 
End Class 

Public Class A 
    Public Overridable Property F As X 
End Class 

Public Class B 
    Inherits A 
    Private _f As Y 
    Public Overrides Property F As X 
     Get 
      Return _f 
     End Get 
     Set(value As X) 
      _f = DirectCast(value, X) 
     End Set 
    End Property 
End Class 

用法:

Dim a As New A() 
Dim x As New X() 
Dim b As New B() 
Dim y As New Y() 

a.F = x 
Console.WriteLine(a.F.Z) 
' Console.WriteLine(DirectCast(a.F, Y).Foo()) ' InvalidCastException 

b.F = y 
Console.WriteLine(b.F.Z) 
Console.WriteLine(DirectCast(b.F, Y).Foo()) ' OK 

输出

X
ÿ
酒吧

+0

问题在于,这是一个更大代码库的一部分,它严重依赖于使用A类。我曾考虑过做出这样的改变,但这意味着对引用A的所有事物都进行彻底的改变。我改变得越多,意想不到的后果就越多。 –

+0

@JeremyFriesen:既然'Y'继承'X',即使它被声明为'F As X',你也可以设置'F = Y'。要使用实际的'Y'只需检查其类型:'如果F.GetType()是GetType(Y)则:DirectCast(F,Y).DoStuff():End If'。 –

+0

@JeremyFriesen:这是一个小提琴,展示了我刚刚描述的内容:https://dotnetfiddle.net/a4jqbQ(这可以在任何派生类中的任何地方和任何派生类中使用,并且您不需要在属性的“Set”方法中执行此操作) –