(Die Seite wurde neu angelegt: „<syntaxhighlight lang="c#"> record Point (int X, int Y) : IAdditionOperators<Point, Point, Point> { public static Point operator + (Point left, Point right) =…“) |
Keine Bearbeitungszusammenfassung |
||
Zeile 1: | Zeile 1: | ||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
// NB: This demo requires .NET 7 - https://dotnet.microsoft.com/en-us/download/dotnet/7.0 | |||
// | |||
// .NET 7 includes the IAdditionOperators interface, which is defined as follows: | |||
// | |||
// public interface IAdditionOperators<TSelf, TOther, TResult> | |||
// where TSelf : IAdditionOperators<TSelf, TOther, TResult> | |||
// { | |||
// static abstract TResult operator + (TSelf left, TOther right); | |||
// static abstract TResult operator checked + (TSelf left, TOther right); | |||
// } | |||
// | |||
// Let's implement this interface: | |||
record Point (int X, int Y) : IAdditionOperators<Point, Point, Point> | record Point (int X, int Y) : IAdditionOperators<Point, Point, Point> | ||
{ | { | ||
Zeile 7: | Zeile 20: | ||
public static Point operator checked + (Point left, Point right) => | public static Point operator checked + (Point left, Point right) => | ||
new Point (checked(left.X + right.X), checked(left.Y + right.Y)); | new Point (checked(left.X + right.X), checked(left.Y + right.Y)); | ||
} | |||
// As in the preceding example, you can call the operator polymorphically via a constrained type parameter. | |||
// This time, we'll demo it by writing an extension method that sums a sequence of values: | |||
static class Extensions | |||
{ | |||
public static T SumEx<T> (this IEnumerable<T> source) where T : IAdditionOperators<T, T, T> | |||
{ | |||
using var rator = source.GetEnumerator(); | |||
if (!rator.MoveNext()) throw new InvalidOperationException ("Empty sequence"); | |||
T total = rator.Current; | |||
while (rator.MoveNext()) | |||
// Here's where we use the addition operator defined in IAdditionOperators<T,T,T> | |||
total += rator.Current; | |||
return total; | |||
} | |||
} | |||
// Demo: | |||
void Main() | |||
{ | |||
var point1 = new Point (1, 1); | |||
var point2 = new Point (2, 2); | |||
var point3 = new Point (3, 3); | |||
new[] { point1, point2, point3 }.SumEx().Dump ("sum of points"); | |||
// The numeric types in .NET 7 all implement IAdditionOperators, so we can also use | |||
// our SumEx method to sum any built-in numeric type: | |||
new[] { 1, 2, 3 }.SumEx().Dump ("sum of numbers (int)"); | |||
new[] { 1.1, 2.2, 3.3 }.SumEx().Dump ("sum of numbers (double)"); | |||
// The .NET numeric types implement a whole bunch of other new interfaces, encompassed | |||
// by INumberBase<TSelf> and INumber<TSelf>. | |||
// Click the following button to see how these interfaces are defined. | |||
new LINQPad.Controls.Button ( | |||
"Show me what the INumberBase/INumber interfaces look like...", | |||
_ => Util.OpenILSpy (typeof (System.Numerics.INumberBase<>))).Dump(); | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |
Aktuelle Version vom 16. März 2023, 18:16 Uhr
// NB: This demo requires .NET 7 - https://dotnet.microsoft.com/en-us/download/dotnet/7.0
//
// .NET 7 includes the IAdditionOperators interface, which is defined as follows:
//
// public interface IAdditionOperators<TSelf, TOther, TResult>
// where TSelf : IAdditionOperators<TSelf, TOther, TResult>
// {
// static abstract TResult operator + (TSelf left, TOther right);
// static abstract TResult operator checked + (TSelf left, TOther right);
// }
//
// Let's implement this interface:
record Point (int X, int Y) : IAdditionOperators<Point, Point, Point>
{
public static Point operator + (Point left, Point right) =>
new Point (left.X + right.X, left.Y + right.Y);
public static Point operator checked + (Point left, Point right) =>
new Point (checked(left.X + right.X), checked(left.Y + right.Y));
}
// As in the preceding example, you can call the operator polymorphically via a constrained type parameter.
// This time, we'll demo it by writing an extension method that sums a sequence of values:
static class Extensions
{
public static T SumEx<T> (this IEnumerable<T> source) where T : IAdditionOperators<T, T, T>
{
using var rator = source.GetEnumerator();
if (!rator.MoveNext()) throw new InvalidOperationException ("Empty sequence");
T total = rator.Current;
while (rator.MoveNext())
// Here's where we use the addition operator defined in IAdditionOperators<T,T,T>
total += rator.Current;
return total;
}
}
// Demo:
void Main()
{
var point1 = new Point (1, 1);
var point2 = new Point (2, 2);
var point3 = new Point (3, 3);
new[] { point1, point2, point3 }.SumEx().Dump ("sum of points");
// The numeric types in .NET 7 all implement IAdditionOperators, so we can also use
// our SumEx method to sum any built-in numeric type:
new[] { 1, 2, 3 }.SumEx().Dump ("sum of numbers (int)");
new[] { 1.1, 2.2, 3.3 }.SumEx().Dump ("sum of numbers (double)");
// The .NET numeric types implement a whole bunch of other new interfaces, encompassed
// by INumberBase<TSelf> and INumber<TSelf>.
// Click the following button to see how these interfaces are defined.
new LINQPad.Controls.Button (
"Show me what the INumberBase/INumber interfaces look like...",
_ => Util.OpenILSpy (typeof (System.Numerics.INumberBase<>))).Dump();
}