创建一个包含泛型委托的类

时间:2014-05-21 16:07:07

标签: c# .net vb.net generics delegates

我正在尝试创建一个包含两个(或更多)通用委托作为属性的类。这样我就可以将对象传递给方法,并且只对该方法使用一个参数。问题是我得到一个警告来指定一个类型,但我还不知道类型。重点是推迟类型声明,直到对象被实例化。

这是一些虚拟代码虚拟代码,用于显示我想要做的事情。

Public Function Method1()
     Dim _container as Container = new Container()
     _container.Property1 = //Here create delegate with type string
     _container.Property2 = //Here create delegate with type integer
     Method3(_container)
End Function

Public Function Method2()
     Dim _container as Container = new Container()
     _container.Property1 = //Here create delegate with type Integer
     _container.Property2 = //Here create delegate with type integer
     Method3(_container)
End Function

Public Function Method3(container as Container)
  //execute type specific code and the delegates
  //Throw exception when type is not supported (yet)
end Function

public Class Container
      Property Property1 as MyDel(of T)
      Property Property2 as MyDel(of T)
end Class

Public delegate function Mydel(of T)()

就是这样。这一点的意义在于,在向系统添加新信息/功能时,很容易创建一个名为Method4的新方法,该方法根据需要使用参数(当然创建将作为委托执行的方法)。

我想把两个代表放在一个类中,因为它们是它们之间的连接,属于一起的东西应该放在一个类中;就像Person类可以保存名称和地址一样。

这段代码不起作用,因为Container需要一个Type T,这意味着Method3需要一个特定的类型,但我不能这样做,因为我不能用我所展示的不同参数调用Method3。我尝试使用包装器类,但是一直需要类型规范。

我知道你可以做到这一点

Public Property TestProp() As [Delegate]
    Get

    End Get
    Set(ByVal Value As [Delegate])

    End Set
End Property

[来源:http://www.xtremedotnettalk.com/showthread.php?t=96800]

但这不是通用的。我错过了什么?

顺便说一下,这是一个带有两个参数的代码调用方法3的优化。这似乎工作正常。然后我想尝试只使用一个参数,这将使系统更容易理解。

我的旧代码看起来像这样:

Public function OldMethod1()
    Dim del1 as Mydel(of Integer) = AddressOf SomeMethod
    Dim del2 as MyDel(of String) = AddressOf SomeOtherMethod
    oldMethod3(del1, del2)
end Function

Public function OldMethod2()
    Dim del1 as Mydel(of String) = AddressOf AnOtherMethod
    Dim del2 as MyDel(of String) = AddressOf AgainSomeOtherMethod
    oldMethod4(del1, del2)
end Function

Public Function oldMethod3(del1 as Mydel(of Integer), del2 as Mydel(of string))
    //execute delegates
end Function

Public Function oldMethod4(del1 as Mydel(of string), del2 as Mydel(of string))
    //execute delegates
end Function

当阅读这段代码时,我看到它只是决定执行流程的参数类型。因此,如果您可以确定通用的子类型,您就知道该怎么做。这似乎是可能的(使用typeOf和/或GetType),所以接下来要做的是创建一个可以替代'del1'的通用参数对象(我现在意识到我甚至更进了一步并创建了容器类保存两个参数)。

C#或VB.net中的任何答案都可以。我同时使用它们。

1 个答案:

答案 0 :(得分:0)

问题有点令人困惑,所以这可能不是一个答案,但评论太长了!我想您要做的是使用Action(Of T)作为Container.Property1Container.Property2的类型。

这样的事情(这将使用语言:VB程序在LINQPad中运行):

Sub Main

    Dim c1 = New Container(Of String, String)()
    c1.Property1 = AddressOf Method1
    c1.Property2 = AddressOf Method1
    Method3(c1)

    Dim c2 = New Container(Of String, Integer)()
    c2.Property1 = AddressOf Method1
    c2.Property2 = AddressOf Method2
    Method3(c2)

End Sub

Public Sub Method1(x As String)
    Console.WriteLine("Method1: {0}", x)
End Sub

Public Sub Method2(x As Integer)
    Console.WriteLine("Method2: {0}", x)
End Sub

Public Sub Method3(Of T1, T2)(container as Container(Of T1, T2))
    Console.WriteLine("Method3 got {0}, {1}", GetType(T1), GetType(T2))
    ' Not sure how you would actually call the delegates
    If GetType(T1) = GetType(String) Then
        container.Property1.DynamicInvoke("Hello")
    ElseIf GetType(T1) = GetType(Integer) Then
        container.Property1.DynamicInvoke(123)
    End If
    If GetType(T2) = GetType(String) Then
        container.Property2.DynamicInvoke("World")
    ElseIf GetType(T2) = GetType(Integer) Then
        container.Property2.DynamicInvoke(456)
    End If
End Sub

Public Class Container(Of T1, T2)
    Public Property Property1 As Action(Of T1)
    Public Property Property2 As Action(Of T2)
End Class

这会产生以下结果:

Method3 got System.String, System.String
Method1: Hello
Method1: World
Method3 got System.String, System.Int32
Method1: Hello
Method2: 456