如何使用泛型方法替换重复的属性?

时间:2011-07-29 19:56:05

标签: .net vb.net generics

目前我的代码具有以下属性:

  Private _queueRetriever As Services.IQueueRetriever
  Public ReadOnly Property QueueRetriever As Services.IQueueRetriever
     Get
        If _queueRetriever Is Nothing Then
           RemotingSetup.RegisterHttpBinaryChannel()
           _queueRetriever = RemotingFactory.CreateProxy(Of Services.IQueueRetriever)(Options.DevLocal)
        End If

        Return _queueRetriever
     End Get
  End Property

  Private _queueCountRetriever As Services.IQueueCounter
  Public ReadOnly Property QueueCounter As Services.IQueueCounter
     Get
        If _queueCountRetriever Is Nothing Then
           RemotingSetup.RegisterHttpBinaryChannel()
           _queueCountRetriever = RemotingFactory.CreateProxy(Of Services.IQueueCounter)(Options.DevLocal)
        End If

        Return _queueCountRetriever
     End Get
  End Property

如您所见,两个属性的代码基本相同。只有类型不同。我在泛型方法方面不是很有经验,但我觉得我应该能够使用泛型使这个代码更加DRY。可以这样做,还是这不是通用方法的工作?

修改

根据Marc的回答,我想出了以下内容:

  Protected Services As New Dictionary(Of Type, Object)

  Protected Function CreateService(Of T)() As T
     If Not Services.ContainsKey(GetType(T)) Then

        RemotingSetup.RegisterHttpBinaryChannel()
        Services.Add(GetType(T), RemotingFactory.CreateProxy(Of T)(Options.DevLocal))

     End If

     Return DirectCast(Services(GetType(T)), T)
  End Function

当然,可以这样使用:

Me.CreateService(Of IService).Foo()

3 个答案:

答案 0 :(得分:4)

你可以做(​​并且为转换成C#而道歉,但我的VB技能在这里缺乏细微之处 - 我确信它在VB中也可以正常工作)

private T GetProxy<T>(ref T field) where T : class {
    if(field == null) {
        RemotingSetup.RegisterHttpBinaryChannel();
        field = RemotingFactory.CreateProxy<T>(Options.DevLocal);
    }
    return field;
}

使用:

private Services.IQueueCounter queueCounter;
public Services.IQueueCounter QueueCounter {
    get { return GetProxy(ref queueCounter); }
}
private Services.IQueueRetriever queueRetriever;
public Services.IQueueRetriever QueueRetriever {
    get { return GetProxy(ref queueRetriever); }
}

答案 1 :(得分:0)

你可以创建一个私有的泛型方法,让你回到适当的通道,但在这种情况下你基本上会用1行代码和一个双行方法调用替换2行代码。这可能是不值得的,除了你添加第三种类型的频道,你会在第三种情况下忘记RemotingSetup.RegisterHttpBinaryChannel行的危险。

答案 2 :(得分:0)

您无法在.Net

中创建通用属性

您可以做的是创建一个在Get:

中调用的通用方法
  Private _queueCountRetriever As Services.IQueueCounter
  Public ReadOnly Property QueueCounter As Services.IQueueCounter
     Get
        Return MyGet(Of QueueCounter ,IQueueCounter )(_queueCountRetriever)
     End Get
  End Property

  Private Function MyGet(Of T As IT, IT)(ByRef propertyVar As T ) As IT
       If propertyVar Is Nothing Then
           RemotingSetup.RegisterHttpBinaryChannel()
           propertyVar = RemotingFactory.CreateProxy(Of IT)(Options.DevLocal)
        End If
  End Function