Skip to content

Commit 7f27f20

Browse files
CopilotBillWagner
andcommitted
Add DateOnly example and documentation to indexers article
Co-authored-by: BillWagner <[email protected]>
1 parent a0d5870 commit 7f27f20

File tree

5 files changed

+85
-4
lines changed

5 files changed

+85
-4
lines changed

docs/csharp/programming-guide/indexers/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ Another common scenario is when you need to model a dictionary or a map. This sc
5555

5656
In this example, the `ArgsAction` collection maps closely to the underlying collection. The `get` determines if a given option is configured. If so, it returns the <xref:System.Action> associated with that option. If not, it returns an <xref:System.Action> that does nothing. The public accessor doesn't include a `set` accessor. Rather, the design is using a public method for setting options.
5757

58+
### Date-based indexers
59+
60+
When working with date-based data, you can use either <xref:System.DateTime> or <xref:System.DateOnly> as indexer keys. Use <xref:System.DateOnly> when you only need the date part and want to avoid time-related complications. The following example shows a temperature tracking system that uses `DateOnly` as the primary indexer key:
61+
62+
:::code language="csharp" source="./snippets/indexers/DateOnlyIndexer.cs":::
63+
64+
This example demonstrates both `DateOnly` and `DateTime` indexers. While the `DateOnly` indexer is the primary interface, the `DateTime` overload provides convenience by extracting only the date portion. This approach ensures that all temperature data for a given day is treated consistently, regardless of the time component.
65+
5866
### Multi-Dimensional Maps
5967

6068
You can create indexers that use multiple arguments. In addition, those arguments aren't constrained to be the same type.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Indexers;
5+
6+
public class DailyTemperatureData
7+
{
8+
private readonly Dictionary<DateOnly, (double High, double Low)> _temperatureData = new();
9+
10+
// Indexer using DateOnly for date-only scenarios
11+
public (double High, double Low) this[DateOnly date]
12+
{
13+
get
14+
{
15+
if (_temperatureData.TryGetValue(date, out var temp))
16+
{
17+
return temp;
18+
}
19+
throw new KeyNotFoundException($"No temperature data available for {date:yyyy-MM-dd}");
20+
}
21+
set
22+
{
23+
_temperatureData[date] = value;
24+
}
25+
}
26+
27+
// Overload using DateTime for convenience, but only uses the date part
28+
public (double High, double Low) this[DateTime dateTime]
29+
{
30+
get => this[DateOnly.FromDateTime(dateTime)];
31+
set => this[DateOnly.FromDateTime(dateTime)] = value;
32+
}
33+
34+
public bool HasDataFor(DateOnly date) => _temperatureData.ContainsKey(date);
35+
36+
public IEnumerable<DateOnly> AvailableDates => _temperatureData.Keys;
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using Indexers;
3+
4+
namespace DateOnlyExample;
5+
6+
class Program
7+
{
8+
static void Main()
9+
{
10+
var temperatureData = new DailyTemperatureData();
11+
12+
// Store temperature data using DateOnly
13+
var today = DateOnly.FromDateTime(DateTime.Today);
14+
temperatureData[today] = (75.2, 62.1);
15+
temperatureData[today.AddDays(1)] = (78.5, 64.3);
16+
temperatureData[today.AddDays(-1)] = (72.8, 59.7);
17+
18+
// Retrieve data using DateOnly
19+
Console.WriteLine($"Today's temperature: High {temperatureData[today].High}°F, Low {temperatureData[today].Low}°F");
20+
21+
// Can also use DateTime - only the date part is used
22+
var tomorrow = DateTime.Today.AddDays(1);
23+
Console.WriteLine($"Tomorrow's temperature: High {temperatureData[tomorrow].High}°F, Low {temperatureData[tomorrow].Low}°F");
24+
25+
// Show available dates
26+
Console.WriteLine("Available temperature data for:");
27+
foreach (var date in temperatureData.AvailableDates)
28+
{
29+
Console.WriteLine($" {date:yyyy-MM-dd}");
30+
}
31+
}
32+
}

docs/csharp/programming-guide/indexers/snippets/indexers/Indexers.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net9.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<Nullable>enable</Nullable>
77
<ImplicitUsings>enable</ImplicitUsings>
8-
<LangVersion>preview</LangVersion>
98
</PropertyGroup>
109

1110
</Project>

docs/csharp/programming-guide/indexers/snippets/indexers/indexer-2.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
namespace Indexers;
22

3-
public class ReadOnlySampleCollection<T>(params IEnumerable<T> items)
3+
public class ReadOnlySampleCollection<T>
44
{
55
// Declare an array to store the data elements.
6-
private T[] arr = [.. items];
6+
private T[] arr;
7+
8+
public ReadOnlySampleCollection(params T[] items)
9+
{
10+
arr = items;
11+
}
712

813
public T this[int i] => arr[i];
914

0 commit comments

Comments
 (0)