Warm greetings! This lesson introduces data streams, which are essentially continuous datasets. Imagine a weather station or a gaming application gathering data every second — both generate data streams! We will learn how to handle these data streams using C# by accessing individual elements, slicing segments, and converting these streams into strings for easier handling.
In C#, data streams can be represented using collections such as arrays or lists. We will use a class to encapsulate operations related to these data streams in our C# application. Let's consider a simple C# class named DataStream
:
C#1using System; 2using System.Collections.Generic; 3 4class DataStream 5{ 6 private List<Dictionary<string, int>> data; 7 8 public DataStream(List<Dictionary<string, int>> data) 9 { 10 this.data = data; 11 } 12}
To use this, we create a sample data stream as an instance of our DataStream
class, where each element is a dictionary with key-value pairs:
C#1class Program 2{ 3 static void Main() 4 { 5 var stream = new DataStream(new List<Dictionary<string, int>> 6 { 7 new Dictionary<string, int> { {"id", 1}, {"value", 100} }, 8 new Dictionary<string, int> { {"id", 2}, {"value", 200} }, 9 new Dictionary<string, int> { {"id", 3}, {"value", 300} }, 10 new Dictionary<string, int> { {"id", 4}, {"value", 400} } 11 }); 12 } 13}
To look into individual elements of a data stream, we use zero-based indexing. The Get
method we introduce below fetches the i
-th element from the data stream:
C#1using System; 2using System.Collections.Generic; 3 4class DataStream 5{ 6 private List<Dictionary<string, int>> data; 7 8 public DataStream(List<Dictionary<string, int>> data) 9 { 10 this.data = data; 11 } 12 13 public Dictionary<string, int> Get(int i) 14 { 15 if (i >= 0 && i < data.Count) 16 return data[i]; 17 18 return null; // Returning null if index is out of bounds 19 } 20}
Here's how we can use the Get
method:
C#1class Program 2{ 3 static void Main() 4 { 5 var stream = new DataStream(new List<Dictionary<string, int>> 6 { 7 new Dictionary<string, int> { {"id", 1}, {"value", 100} }, 8 new Dictionary<string, int> { {"id", 2}, {"value", 200} }, 9 new Dictionary<string, int> { {"id", 3}, {"value", 300} }, 10 new Dictionary<string, int> { {"id", 4}, {"value", 400} } 11 }); 12 13 var element = stream.Get(2); 14 if (element != null) 15 Console.WriteLine(element["id"]); // Output: 3 16 17 element = stream.Get(-1); 18 Console.WriteLine(element == null); // Output: True 19 } 20}
In essence, stream.Get(2)
fetches us the dictionary with { "id": 3, "value": 300 }
.
To fetch a range of elements, we can use slicing. C# offers several ways to achieve this, such as using LINQ to select a range from our data stream. Here's how you might implement a Slice
method:
C#1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5class DataStream 6{ 7 private List<Dictionary<string, int>> data; 8 9 public DataStream(List<Dictionary<string, int>> data) 10 { 11 this.data = data; 12 } 13 14 public List<Dictionary<string, int>> Get(int i) 15 { 16 if (i >= 0 && i < data.Count) 17 return data[i]; 18 19 return null; // Returning null if index is out of bounds 20 } 21 22 public List<Dictionary<string, int>> Slice(int i, int j) 23 { 24 return data.Skip(i).Take(j - i).ToList(); 25 } 26}
Here's a quick usage example:
C#1class Program 2{ 3 static void Main() 4 { 5 var stream = new DataStream(new List<Dictionary<string, int>> 6 { 7 new Dictionary<string, int> { {"id", 1}, {"value", 100} }, 8 new Dictionary<string, int> { {"id", 2}, {"value", 200} }, 9 new Dictionary<string, int> { {"id", 3}, {"value", 300} }, 10 new Dictionary<string, int> { {"id", 4}, {"value", 400} } 11 }); 12 13 var slicedStream = stream.Slice(1, 3); 14 foreach (var item in slicedStream) 15 { 16 Console.WriteLine(item["id"]); // Output: 2, 3 17 } 18 } 19}
For better readability, we may want to convert our data streams into strings. In C#, we can use String.Join
along with JSON serialization for this. Below is the example of implementing the ToString
method:
C#1using System; 2using System.Collections.Generic; 3using System.Text.Json; 4 5class DataStream 6{ 7 private List<Dictionary<string, int>> data; 8 9 public DataStream(List<Dictionary<string, int>> data) 10 { 11 this.data = data; 12 } 13 14 public Dictionary<string, int> Get(int i) 15 { 16 if (i >= 0 && i < data.Count) 17 return data[i]; 18 19 return null; 20 } 21 22 public List<Dictionary<string, int>> Slice(int i, int j) 23 { 24 return data.Skip(i).Take(j - i).ToList(); 25 } 26 27 public override string ToString() 28 { 29 var serializedItems = data.Select(item => JsonSerializer.Serialize(item)); 30 return "[" + string.Join(", ", serializedItems) + "]"; 31 } 32}
To demonstrate:
C#1class Program 2{ 3 static void Main() 4 { 5 var stream = new DataStream(new List<Dictionary<string, int>> 6 { 7 new Dictionary<string, int> { {"id", 1}, {"value", 100} }, 8 new Dictionary<string, int> { {"id", 2}, {"value", 200} }, 9 new Dictionary<string, int> { {"id", 3}, {"value", 300} }, 10 new Dictionary<string, int> { {"id", 4}, {"value", 400} } 11 }); 12 13 Console.WriteLine(stream.ToString()); 14 // Output: [{"id":1,"value":100},{"id":2,"value":200},{"id":3,"value":300},{"id":4,"value":400}] 15 } 16}
In this lesson, we explored data streams and how to represent and manipulate them using C# collections like lists. We crafted a class that encapsulates operations on data streams in C#, including accessing elements, slicing ranges, and converting streams to string representations.
Now it's time to apply your newfound knowledge in the practice exercises that follow!