我有这段代码,原始代码here,我需要修改以在字符串列表中插入输出字符串。
我是怎么做到的?
private static List<string> list_of_proc = new List<string>();
static void Run<T>(Func<IObservable<T>> f, Action a)
{
Action<string> messageTarget = (x) => list_of_proc.Add(x);
using (f().Subscribe(t => Console.WriteLine(t), p => messageTarget(p)))
{
Console.ReadLine();
Console.WriteLine();
}
}
我的操作messageTarget无法编译。
输出错误:
1>Program.cs(20,34,20,59): error CS1660: Cannot convert lambda expression to type 'System.IObserver' because it is not a delegate type 1>Program.cs(20,61,20,82): error CS1593: Delegate 'System.Action' does not take 1 arguments 1>Program.cs(20,61,20,82): error CS1660: Cannot convert lambda expression to type 'System.Threading.CancellationToken' because it is not a delegate type 1>Program.cs(20,66,20,82): error CS1594: Delegate 'System.Action' has some invalid arguments 1>Program.cs(20,80,20,81): error CS1503: Argument 1: cannot convert from 'System.Exception' to 'string'
此代码编译正常,没有错误:
static void Run<T>(Func<IObservable<T>> f, Action a)
{
Action<string> messageTarget = (x) => list_of_proc.Add(x);
using (f().Subscribe(t => Console.WriteLine(t)/*, p => messageTarget(p)*/))
{
Console.ReadLine();
Console.WriteLine();
}
}
订阅具有此表单(System.Reactive.Core.dll,v2.2.5.0):
public static IDisposable Subscribe(this IObservable source, Action onNext);
这个正确的代码:
static void Run<T>(Func<IObservable<T>> f, Action a)
{
Action<string> messageTarget = (x) => list_of_proc.Add(x);
using (f().Subscribe( t => messageTarget(t.ToString())))
{
Console.ReadLine();
Console.WriteLine();
}
}
答案 0 :(得分:2)
.Subscribe(...)
有许多IObservable<T>
个扩展方法。编译器将尝试找到最合适的重载。在您的情况下,它按此顺序尝试这些重载:
IDisposable Subscribe<T>(this IObservable<T> source)
IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted)
void Subscribe<T>(this IObservable<T> source, Action<T> onNext, CancellationToken token)
IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action<Exception> onError)
然而,您的电话是这样的:
.Subscribe(this IObservable<T> source, Action<T> onNext, Action<string> ???)
无匹配,但正试图为您提供有用的提示:
Cannot convert lambda expression to type 'System.IObserver<T>' because it is not a delegate type
Delegate 'System.Action' does not take 1 arguments
Cannot convert lambda expression to type 'System.Threading.CancellationToken' because it is not a delegate type
Delegate 'System.Action<string>' has some invalid arguments
每个人都有效地尝试匹配上述重载之一。
您的代码中不清楚的是运行代码时T
的实际类型。为Console.WriteLine(t)
类型t
调用T
意味着您可能强制t.ToString()
输出结果 - 这并不会产生有意义的结果。
然后使用Action<T>
来跟进Action<string>
也没有意义,因为string
不是Exception
而且那里有.Subscribe(...)
,而{&#39}没有明确Action<string>
的{{1}}超载。
我认为你需要的是这样的:
static IObservable<IList<string>> Run<T>(Func<IObservable<T>> f)
{
return Observable
.Defer(f)
.Select(t => t.ToString())
.ToArray()
.Select(ss => ss.ToList());
}
或者,或许,这个:
static IObservable<IList<string>> Run<T>(Func<IObservable<T>> f, Func<T, string> toString)
{
return Observable
.Defer(f)
.Select(t => toString(t))
.ToArray()
.Select(ss => ss.ToList());
}
然后你可以这样称呼:
Run<int>(() => Observable.Range(0, 3), n => n.ToString())
.Subscribe(results => /* handle list of results */);
答案 1 :(得分:1)
您正在使用IObserver作为该函数的第一个参数,但实际上您给它一个委托,并且编译器告诉您它不是委托。 就这么简单。
答案 2 :(得分:0)
您的Subscribe
方法是扩展方法。 this
参数隐式地是您调用该方法的对象。这意味着您只应将Action
委托作为唯一参数传递。
f().Subscribe(() => Console.WriteLine("Hello"))