我有这种扩展方法:
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 :(得分: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()
方法提供。
这意味着您必须进行两次方法调用而不是一次,但这是您为“部分”类型推断所付出的代价:(
答案 1 :(得分:0)
您必须明确指定所有参数,或者让所有参数由args隐式决定。 C#不支持部分参数规范。