Zuletzt bearbeitet vor einem Jahr
von Marc Kruse

Sandkasten/Source-Code: Unterschied zwischen den Versionen

(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();
}