Trong ví dụ này hoàn toàn là thực hành, đây là những gì tôi muốn quay trở lại:Có một toán tử hoạt động như Quét nhưng hãy để tôi trả về một IObservable <TResult> thay vì IObservable <TSource>?
Nếu hai học sinh tham gia một trường trong một khoảng thời gian nhất định, nói, 2 giây, sau đó tôi muốn cấu trúc dữ liệu trả về cả hai sinh viên, trường họ tham gia và khoảng thời gian giữa họ tham gia.
Tôi đã suy nghĩ cùng những dòng này:
class Program
{
static void Main(string[] args)
{
ObserveStudentsJoiningWithin(TimeSpan.FromSeconds(2));
}
static void ObserveStudentsJoiningWithin(TimeSpan timeSpan)
{
var school = new School("School 1");
var admissionObservable =
Observable.FromEventPattern<StudentAdmittedEventArgs>(school, "StudentAdmitted");
var observable = admissionObservable.TimeInterval()
.Scan((current, next) =>
{
if (next.Interval - current.Interval <= timeSpan)
{
// But this won't work for me because
// this requires me to return a TSource
// and not a TResult
}
});
var subscription = observable.Subscribe(TimeIntervalValueHandler);
school.FillWithStudentsAsync(10, TimeSpan.FromSeconds(3));
school.FillWithStudentsAsync(8, TimeSpan.FromSeconds(1));
Console.WriteLine("Press any key to exit the program");
Console.ReadKey();
subscription.Dispose();
}
}
Và đây là lĩnh vực:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace SchoolManagementSystem
{
public class Student
{
private static int _studentNumber;
public Student(string name)
{
Name = name;
}
public string Name { get; set; }
public static Student CreateRandom()
{
var name = string.Format($"Student {++_studentNumber}");
return new Student(name);
}
public override string ToString()
{
return Name;
}
}
public class School: IEnumerable<Student>
{
private List<Student> _students;
public event StudentAdmitted StudentAdmitted;
public string Name { get; set; }
public School(string name)
{
Name = name;
_students = new List<Student>();
}
public void AdmitStudent(Student student)
{
if (!_students.Contains(student))
{
_students.Add(student);
OnStudentAdmitted(this, student);
}
}
protected virtual void OnStudentAdmitted(School school, Student student)
{
var args = new StudentAdmittedEventArgs(school, student);
StudentAdmitted?.Invoke(this, args);
}
public IEnumerator<Student> GetEnumerator()
{
return _students.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public delegate void StudentAdmitted(object sender, StudentAdmittedEventArgs args);
public class StudentAdmittedEventArgs : EventArgs
{
public StudentAdmittedEventArgs(School school, Student student): base()
{
School = school;
Student = student;
}
public School School { get; protected set; }
public Student Student { get; protected set; }
}
public static class Extensions
{
public async static void FillWithStudentsAsync(this School school, int howMany, TimeSpan gapBetweenEachAdmission)
{
if (school == null)
throw new ArgumentNullException("school");
if (howMany < 0)
throw new ArgumentOutOfRangeException("howMany");
if (howMany == 1)
{
school.AdmitStudent(Student.CreateRandom());
return;
}
for (int i = 0; i < howMany; i++)
{
await Task.Delay(gapBetweenEachAdmission);
school.AdmitStudent(Student.CreateRandom());
}
}
}
}
Tuy nhiên, các nhà điều hành Scan
cho phép tôi chỉ trả lại một quan sát được của cùng TSource
. Select
cũng sẽ không làm việc ở đây vì tôi không có thể nhìn về phía trước (một cái gì đó mà tôi có thể làm gì với Scan
) và dự án mục hiện tại cùng với người tiếp theo, mặc dù Select
cho phép tôi chuyển đổi TSource
vào TResult
.
Tôi đang tìm kiếm thứ gì đó ở giữa.
['Observable.Scan'] (https://msdn.microsoft.com/en-us/library/hh212007.aspx) không cho phép bạn trả lại loại bộ tích lũy. – Lee
Tệ của tôi. Bạn đúng. Nếu bạn đặt nó xuống như một câu trả lời? –