Skip to content

Add DateOnly guidance and examples to indexers documentation #47727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/csharp/programming-guide/indexers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ Another common scenario is when you need to model a dictionary or a map. This sc

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.

### Date-based indexers

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:

:::code language="csharp" source="./snippets/indexers/DateOnlyIndexer.cs":::

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.

### Multi-Dimensional Maps

You can create indexers that use multiple arguments. In addition, those arguments aren't constrained to be the same type.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;

namespace Indexers;

public class DailyTemperatureData
{
private readonly Dictionary<DateOnly, (double High, double Low)> _temperatureData = new();

// Indexer using DateOnly for date-only scenarios
public (double High, double Low) this[DateOnly date]
{
get
{
if (_temperatureData.TryGetValue(date, out var temp))
{
return temp;
}
throw new KeyNotFoundException($"No temperature data available for {date:yyyy-MM-dd}");
}
set
{
_temperatureData[date] = value;
}
}

// Overload using DateTime for convenience, but only uses the date part
public (double High, double Low) this[DateTime dateTime]
{
get => this[DateOnly.FromDateTime(dateTime)];
set => this[DateOnly.FromDateTime(dateTime)] = value;
}

public bool HasDataFor(DateOnly date) => _temperatureData.ContainsKey(date);

public IEnumerable<DateOnly> AvailableDates => _temperatureData.Keys;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using Indexers;

namespace DateOnlyExample;

class Program
{
static void Main()
{
var temperatureData = new DailyTemperatureData();

// Store temperature data using DateOnly
var today = DateOnly.FromDateTime(DateTime.Today);
temperatureData[today] = (75.2, 62.1);
temperatureData[today.AddDays(1)] = (78.5, 64.3);
temperatureData[today.AddDays(-1)] = (72.8, 59.7);

// Retrieve data using DateOnly
Console.WriteLine($"Today's temperature: High {temperatureData[today].High}°F, Low {temperatureData[today].Low}°F");

// Can also use DateTime - only the date part is used
var tomorrow = DateTime.Today.AddDays(1);
Console.WriteLine($"Tomorrow's temperature: High {temperatureData[tomorrow].High}°F, Low {temperatureData[tomorrow].Low}°F");

// Show available dates
Console.WriteLine("Available temperature data for:");
foreach (var date in temperatureData.AvailableDates)
{
Console.WriteLine($" {date:yyyy-MM-dd}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>preview</LangVersion>
</PropertyGroup>

</Project>