2012-03-02 106 views
0

我有这样的扩展方法:如何避免指定类型参数

public static void PublishOnClient<THub, T>(this IObservable<T> observable, Expression<Func<THub, dynamic>> expression) where THub : Hub, new() 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression == null) 
     { 
      throw new ArgumentException("'expression' should be a member expression"); 
     } 

     observable.Subscribe(x => Console.WriteLine(memberExpression.Member.Name)); 
    } 

我用它这样的:

Observable.Interval(TimeSpan.FromSeconds(2)) 
      .PublishOnClient<TicketHub, long>(x => x.SomeValue); 

但我宁可喜欢用它,而无需指定这样的T:

Observable.Interval(TimeSpan.FromSeconds(2)) 
      .PublishOnClient<TicketHub>(x => x.SomeValue); 

我根本不在乎T。我想要的只是提供一个THUB类型安全的方式来获取成员属性的字符串。不过,我希望扩展方法在IObservable上可用。我怎么能这样做?

+0

http://blog.slaks.net/2010/12/partial价格-type-in​​ference-in-net.html – SLaks 2012-03-02 22:51:33

回答

3

认为你可以引入一个中间类型,像这样的侥幸:

// All these names are bad... I don't know the domain here :) 
public class Publisher<T> 
{ 
    private readonly IObservable<T> observable; 

    internal Publisher(IObservable<T> observable) 
    { 
     this.observable = observable; 
    } 

    public void OnClient<THub>(Expression<Func<THub, dynamic>> expression) 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression == null) 
     { 
      throw new ArgumentException(...); 
     } 

     string name = memberExpression.Member.Name; 
     observable.Subscribe(x => Console.WriteLine(name)); 
    } 
} 

public static class ObservableExtensions 
{ 
    public static Publisher<T> Publish<T>(this IObservable<T> observable) 
    { 
     return new Publisher<T>(observable); 
    } 
} 

然后,你可以这样调用:

Observable.Interval(TimeSpan.FromSeconds(2)) 
      .Publish().OnClient<TicketHub>(x => x.SomeValue); 

Publish()方法使用的类型推断T,只留下一个类型参数供给OnClient()方法。

这意味着你得把两个方法调用,而不是一个,但这是你付出的要“分”类型推断:(

+0

这很疯狂,让使用变得如此简单。你的代码只有一个小错误。在您的发布方法中,您必须将退货类型更改为发布商 ;-) – Christoph 2012-03-02 23:06:14

+0

@Christoph:完成,谢谢。 – 2012-03-02 23:12:03

0

您必须明确指定所有参数,或者让所有参数都由参数隐式决定。 C#不支持部分参数指定。

+0

不,但你可以绕过它...... – 2012-03-02 22:56:42

+0

这是真的,但它似乎是一个过度的工作量,以避免添加类型参数 – eouw0o83hf 2012-03-02 22:59:51

+0

这取决于它要走多远为了清理代码库的其余部分,花费更多的精力做一些事情是很有意义的。 – 2012-03-02 23:01:06