开发者

How to use generic method to replace duplicated properties?

Currently my code has the following properties:

  Private _queueRetriever As Services.IQueueRetriever
  Public ReadOnly Property QueueRetriever As Services.IQueueRetriever
     Get
        If _queueRetriever Is Nothing Then
           RemotingSetup.RegisterH开发者_运维问答ttpBinaryChannel()
           _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

As you can see, the code is essentially the same for both properties. Only the types are different. I'm not very experienced in generic methods, but I feel like I should be able to make this code more DRY using generics. Can it be done or is this not a job for generic methods?

EDIT

Building on Marc's answer, I came up with the following:

  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

Which, of course, can be used like so:

Me.CreateService(Of IService).Foo()


You could do (and apologies for switching into C#, but my VB skills lack the subtlety here - I'm sure it works fine in VB too though)

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

with:

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); }
}


You could make a private generic method that gives you back the appropriate channel, but in this case you basically would replace 2 lines of code with 1 line of code and the a two line method call. It may not be worth the effort, other than if you add a third type of channel you would save yourself the danger of in the third case forgetting the RemotingSetup.RegisterHttpBinaryChannel line.


You can't create generic properties in .Net

What you could do, is create a generic method to be called in the 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜