Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A .NET 7 új, matematikai vonatkozású általános felületeket vezet be az alaposztály-kódtárba. Ezeknek az interfészeknek a rendelkezésre állása azt jelenti, hogy egy általános típus vagy metódus típusparaméterét "számszerű" értékre korlátozhatja. Emellett a C# 11-et és újabb verziót is használhatja a felülettagok definiálásáhozstatic virtual. Mivel az operátorokat static-ként kell deklarálni, ez az új C#-funkció lehetővé teszi, hogy az operátorok a számszerű típusok új felületeiben deklarálhatók legyenek.
Ezek az újítások együttesen lehetővé teszik a matematikai műveletek általános végrehajtását, vagyis anélkül, hogy pontosan ismernie kellene a használni kívánt típust. Ha például olyan metódust szeretne írni, amely két számot ad hozzá, korábban minden típushoz (például static int Add(int first, int second) és static float Add(float first, float second)) hozzá kellett adnia a metódus túlterhelését. Most már írhat egyetlen általános metódust, amelyben a típusparaméter számszerű típusra van korlátozva. Például:
static T Add<T>(T left, T right)
where T : INumber<T>
{
return left + right;
}
Ebben a metódusban a típusparaméter T az új INumber<TSelf> felületet megvalósító típusra van korlátozva.
INumber<TSelf> implementálja az interfészt IAdditionOperators<TSelf,TOther,TResult> , amely a + operátort tartalmazza. Ez lehetővé teszi, hogy a metódus általánosan adja hozzá a két számot. A metódus használható a .NET beépített numerikus típusainak bármelyikével, mert mind frissítve lettek a INumber<TSelf> implementálásához a .NET 7-ben.
A kódtár-szerzők leginkább az általános matematikai felületek előnyeit élvezhetik, mivel a "redundáns" túlterhelések eltávolításával egyszerűsíthetik a kódbázisukat. Más fejlesztők közvetetten is profitálhatnak, mivel az általuk használt API-k több típust is támogathatnak.
Az interfészek
Az interfészek úgy lettek kialakítva, hogy elég részletesek legyenek ahhoz, hogy a felhasználók meg tudják határozni a saját felületeiket a tetején, miközben elég részletesek ahhoz, hogy könnyen felhasználhatók legyenek. Ilyen mértékben van néhány alapvető numerikus felület, amellyel a felhasználók többsége interakcióba lép, például INumber<TSelf> és IBinaryInteger<TSelf>. A részletesebb interfészek, például IAdditionOperators<TSelf,TOther,TResult> és ITrigonometricFunctions<TSelf>, támogatják ezeket a típusokat, és a saját tartományspecifikus numerikus felületeiket definiáló fejlesztők számára érhetők el.
Numerikus felületek
Ez a szakasz az System.Numerics felületeket ismerteti, amelyek a szám-szerű típusokat és a számukra elérhető funkciókat írják le.
| Interfész neve | Leírás |
|---|---|
| IBinaryFloatingPointIeee754<TSelf> | Az IEEE 754 szabványt implementáló bináris lebegőpontos típusok általános API-jait teszi elérhetővé. |
| IBinaryInteger<TSelf> | A2. bináris egész számokhoz gyakran használt API-kat teszi elérhetővé. |
| IBinaryNumber<TSelf> | A bináris számokhoz gyakran használt API-kat tesz elérhetővé. |
| IFloatingPoint<TSelf> | A lebegőpontos típusok gyakran használt API-jait teszi elérhetővé. |
| IFloatingPointIeee754<TSelf> | Az IEEE 754 szabványt megvalósító lebegőpontos típusok számára gyakran használt API-kat tesz elérhetővé. |
| INumber<TSelf> | Hasonló számtípusokhoz (gyakorlatilag a "valós" számtartományhoz) hasonló API-kat tesz elérhetővé. |
| INumberBase<TSelf> | Az összes számtípushoz (gyakorlatilag az "összetett" számtartományhoz) tartozó API-kat teszi elérhetővé. |
| ISignedNumber<TSelf> | Az összes aláírt számtípushoz (például a NegativeOnefogalomhoz) tartozó API-kat teszi elérhetővé. |
| IUnsignedNumber<TSelf> | Az összes nem aláírt számtípushoz gyakran használt API-kat tesz elérhetővé. |
| IAdditiveIdentity<TSelf,TResult> | A fogalmat (x + T.AdditiveIdentity) == xteszi elérhetővé. |
| IMinMaxValue<TSelf> | Bemutatja a(z) T.MinValue és T.MaxValue koncepcióját. |
| IMultiplicativeIdentity<TSelf,TResult> | A fogalmat (x * T.MultiplicativeIdentity) == xteszi elérhetővé. |
1A bináris lebegőpontos típusok a következők Double : (double), Halfés Single (float).
2A bináris egész számtípusok a következők: Byte (byte), Int16 (short), Int32 (int), Int64 (long), Int128, IntPtr (nint), SByte (sbyte), UInt16 (ushort), UInt32 (uint), UInt64 (ulong), UInt128, és UIntPtr (nuint).
A közvetlenül használt felület valószínűleg a INumber<TSelf>, amely nagyjából egy valós számnak felel meg. Ha egy típus implementálja ezt az interfészt, az azt jelenti, hogy egy értéknek van jele (ide tartoznak unsigned a pozitívnak tekintett típusok), és összehasonlítható az azonos típusú más értékekkel.
INumberBase<TSelf> összetettebb fogalmakat, például összetett és képzeletbeli számokat biztosít, például egy negatív szám négyzetgyökét. Más interfészek, például IFloatingPointIeee754<TSelf>azért lettek létrehozva, mert nem minden műveletnek van értelme minden számtípushoz – például egy szám padlójának kiszámítása csak lebegőpontos típusok esetében van értelme. A .NET alaposztálytárban a lebegőpontos típus Double implementálódik IFloatingPointIeee754<TSelf> , de Int32 nem.
Számos interfészt más típusok is implementálnak, például Char, , DateOnlyDateTime, DateTimeOffset, Decimal, Guid, TimeOnlyés TimeSpan.
Az alábbi táblázat az egyes felületek által közzétett alapvető API-kat mutatja be.
| Interfész | API név | Leírás |
|---|---|---|
| IBinaryInteger<TSelf> | DivRem |
A hányadost és a maradékot egyszerre számítja ki. |
LeadingZeroCount |
Megszámolja az első nulla bitek számát a bináris ábrázolásban. | |
PopCount |
Megszámolja a bináris reprezentációban lévő beállított bitek számát. | |
RotateLeft |
Balra elforgatja a biteket, más néven körkörös bal eltolás. | |
RotateRight |
Jobbra elforgatja a biteket, más néven körkörös jobbra váltást. | |
TrailingZeroCount |
Megszámolja a záró nulla bitek számát a bináris ábrázolásban. | |
| IFloatingPoint<TSelf> | Ceiling |
Az értéket a pozitív végtelen felé kerekiti. A +4.5 +5, a -4.5 pedig -4 lesz. |
Floor |
Az értéket negatív végtelen felé kerekíti. A +4.5 +4, a -4.5 pedig -5 lesz. | |
Round |
A megadott kerekítési mód alkalmazásával kerekíti az értéket. | |
Truncate |
Az értéket a nulla irányába kerekíti. A +4.5 +4, a -4.5 pedig -4 lesz. | |
| IFloatingPointIeee754<TSelf> | E |
A típus Euler-számát jelölő értéket kap. |
Epsilon |
A legkisebb, nullánál nagyobb reprezentálható értéket adja meg a típushoz. | |
NaN |
Lekéri a típushoz tartozó NaN értéket. |
|
NegativeInfinity |
Lekéri a típushoz tartozó -Infinity értéket. |
|
NegativeZero |
Lekéri a típushoz tartozó -Zero értéket. |
|
Pi |
Lekéri a típushoz tartozó Pi értéket. |
|
PositiveInfinity |
Lekéri a típushoz tartozó +Infinity értéket. |
|
Tau |
Lekéri a Tau értékét, amely a 2 * Pi típushoz tartozik. |
|
| (Egyéb) | (Implementálja a függvényillesztők alatt felsorolt interfészek teljes készletét.) | |
| INumber<TSelf> | Clamp |
A megadott minimális és maximális értéknél nem kisebb értékre korlátozza az értéket. |
CopySign |
Egy megadott érték előjelét egy másik megadott értékkel megegyezőre állítja. | |
Max |
Két érték közül a nagyobbat adja vissza, és NaN-t ad vissza, ha bármelyik bemenet NaN. |
|
MaxNumber |
Két érték közül a nagyobbat adja eredményül; ha az egyik bemenet a NaN, akkor ezt a számot adja vissza. |
|
Min |
Két érték közül a kisebbet adja eredményül, hacsak egyik bemenet sem egyenlő NaN; különben NaN-t adja vissza. |
|
MinNumber |
Két érték közül a kisebbet adja eredményül. Ha egy bemenet van NaN, akkor a számot adja vissza. |
|
Sign |
Negatív értékeknél -1, nullánál 0, pozitív értékeknél pedig +1 értéket ad vissza. | |
| INumberBase<TSelf> | One |
Megkapja a típus értékét, amely 1. |
Radix |
Lekéri a típus radixát vagy bázist. Int32 visszaadja a 2 értéket. Decimal 10-et ad vissza. | |
Zero |
Lekéri a típus 0 értékét. | |
CreateChecked |
Értéket hoz létre, és OverflowException kivételt dob, ha a bemenet nem fér el.1 | |
CreateSaturating |
Értéket hoz létre, amely T.MinValue vagy T.MaxValue közé van szorítva, ha a bemenet nem fér el.1 |
|
CreateTruncating |
Létrehoz egy értéket egy másik értékből, körbefuttatva, ha a bemenet nem fér el. 1 | |
IsComplexNumber |
Igaz értéket ad vissza, ha az érték nem nulla valós és nem nulla képzetes részből áll. | |
IsEvenInteger |
Igaz értéket ad vissza, ha az érték páros egész szám. A 2.0 true-t ad vissza, és a 2.2 false-t ad vissza. |
|
IsFinite |
Igaz értéket ad vissza, ha az érték nem végtelen és nem NaN. |
|
IsImaginaryNumber |
Igaz értéket ad vissza, ha az érték nulla valós részből áll. Ez azt jelenti, hogy a 0 képzelt, és a 1 + 1i nem az. |
|
IsInfinity |
Igaz értéket ad vissza, ha az érték a végtelent jelöli. | |
IsInteger |
Igaz értéket ad vissza, ha az érték egész szám. A 2.0 és a 3.0 visszaadja a true, míg a 2.2 és a 3.1 visszaadja a false. |
|
IsNaN |
Igaz értéket ad vissza, ha az érték az értéket jelöli NaN. |
|
IsNegative |
Igaz értéket ad vissza, ha az érték negatív. Ide tartozik a -0.0. | |
IsPositive |
Igaz értéket ad vissza, ha az érték pozitív. Ide tartozik a 0 és a +0.0. | |
IsRealNumber |
Igaz értéket ad vissza, ha az értéknek nulla képzelt része van. Ez azt jelenti, hogy a 0 valós, mint minden INumber<T> típus. |
|
IsZero |
Igaz értéket ad vissza, ha az érték nulla. Ebbe beletartozik a 0, a +0,0 és a -0,0. | |
MaxMagnitude |
A nagyobb abszolút értékkel rendelkező értéket adja eredményül, NaN értéket adva vissza, ha bármelyik bemenet NaN. |
|
MaxMagnitudeNumber |
A nagyobb abszolút értékkel rendelkező értéket adja eredményül, és a számot adja vissza, ha egy bemenet van NaN. |
|
MinMagnitude |
Ha bármelyik bemenet NaN, akkor az érték NaN-at adja vissza, amelyiknek kisebb az abszolút értéke. |
|
MinMagnitudeNumber |
Kisebb abszolút értékkel adja vissza az értéket, és a számot adja vissza, ha egy bemenet van NaN. |
|
| ISignedNumber<TSelf> | NegativeOne |
Az értéket -1 kapja a típushoz. |
1A három Create* módszer viselkedésének megértéséhez vegye figyelembe az alábbi példákat.
Példa túl nagy érték megadása esetén:
-
byte.CreateChecked(384)fog dobni egy OverflowException. -
byte.CreateSaturating(384)255 értéket ad vissza, mert a 384 nagyobb, mint Byte.MaxValue (ami 255). -
byte.CreateTruncating(384)128-at ad vissza, mert a legalacsonyabb 8 bitet veszi fel (a 384-nek a hexa-ábrázolása0x0180van, a legalacsonyabb 8 bit pedig0x80128).
Példa, ha túl kicsi értéket ad meg:
-
byte.CreateChecked(-384)fog dobni egy OverflowException. -
byte.CreateSaturating(-384)0 értéket ad vissza, mert -384 kisebb, mint Byte.MinValue (ami 0). -
byte.CreateTruncating(-384)128-at ad vissza, mert a legalacsonyabb 8 bitet veszi fel (a 384-nek a hexa-ábrázolása0xFE80van, a legalacsonyabb 8 bit pedig0x80128).
A Create* metódusok különleges szempontokat is figyelembe vesznek az IEEE 754 lebegőpontos típusok esetében, például float és double, mivel speciális értékekkel PositiveInfinityrendelkeznek , NegativeInfinityés NaN.
Create* Mindhárom API úgy viselkedik, mint CreateSaturating. Bár a MinValue és MaxValue a legnagyobb negatív/pozitív "normál" számot képviselik, a tényleges minimum- és maximumértékek a NegativeInfinity, PositiveInfinity, így inkább ezekhez az értékekhez szorítják őket.
Kezelőfelületek
Az operátori felületek megfelelnek a C# nyelvhez elérhető különböző operátoroknak.
- Kifejezetten nem párosítanak olyan műveleteket, mint a szorzás és az osztás, mivel ez nem minden típusra igaz. Például érvényes,
Matrix4x4 * Matrix4x4deMatrix4x4 / Matrix4x4nem érvényes. - Általában lehetővé teszik, hogy a bemeneti és az eredménytípusok különbözzenek, olyan forgatókönyvek támogatása érdekében, mint például két egész szám elosztása, hogy
double-t kapjunk, vagy egy egész számhalmaz átlagának kiszámítása.
| Interfész neve | Definiált operátorok |
|---|---|
| IAdditionOperators<TSelf,TOther,TResult> | x + y |
| IBitwiseOperators<TSelf,TOther,TResult> |
x & y, 'x | y', x ^ y, és ~x |
| IComparisonOperators<TSelf,TOther,TResult> |
x < y, x > y, x <= yés x >= y |
| IDecrementOperators<TSelf> |
--x és x-- |
| IDivisionOperators<TSelf,TOther,TResult> | x / y |
| IEqualityOperators<TSelf,TOther,TResult> |
x == y és x != y |
| IIncrementOperators<TSelf> |
++x és x++ |
| IModulusOperators<TSelf,TOther,TResult> | x % y |
| IMultiplyOperators<TSelf,TOther,TResult> | x * y |
| IShiftOperators<TSelf,TOther,TResult> |
x << y és x >> y |
| ISubtractionOperators<TSelf,TOther,TResult> | x - y |
| IUnaryNegationOperators<TSelf,TResult> | -x |
| IUnaryPlusOperators<TSelf,TResult> | +x |
Megjegyzés:
Néhány illesztő egy ellenőrzött operátort határoz meg a normál, nem ellenőrzött operátor mellett. Az ellenőrzött operátorok ellenőrzött környezetekben vannak meghívva, és lehetővé teszik, hogy egy felhasználó által definiált típus definiálja a túlcsordulás viselkedését. Ha például egy ellenőrzött operátort implementál, CheckedSubtraction(TSelf, TOther)akkor a nem ellenőrzött operátort is implementálnia kell, például Subtraction(TSelf, TOther).
Függvényfelületek
A függvényfelületek olyan általános matematikai API-kat határoznak meg, amelyek szélesebb körben alkalmazhatók, mint egy adott numerikus interfészre. Ezeket az interfészeket mind implementálja a IFloatingPointIeee754<TSelf>, és a jövőben más releváns típusok is implementálhatják őket.
| Interfész neve | Leírás |
|---|---|
| IExponentialFunctions<TSelf> | Exponenciális függvényeket tesz elérhetővé, amelyek támogatják e^x, e^x - 1, 2^x, 2^x - 1, 10^xés 10^x - 1. |
| IHyperbolicFunctions<TSelf> | Hiperbolikus függvényeket tesz elérhetővé, amelyek támogatják acosh(x), asinh(x), atanh(x), cosh(x), sinh(x)és tanh(x). |
| ILogarithmicFunctions<TSelf> | Feltárja a logaritmikus függvényeket, amelyek támogatják ln(x), ln(x + 1), log2(x), log2(x + 1), log10(x) és log10(x + 1). |
| IPowerFunctions<TSelf> | Az energiafüggvényeket támogatja x^y. |
| IRootFunctions<TSelf> | Gyökérfunkciókat tesz elérhetővé, amelyek támogatják a cbrt(x) és sqrt(x) használatát. |
| ITrigonometricFunctions<TSelf> | Trigonometrikus függvényeket tesz elérhetővé, amelyek támogatják acos(x), asin(x), atan(x), cos(x), sin(x)és tan(x). |
Elemzési és formázási felületek
Az elemzés és a formázás a programozás alapvető fogalmai. Gyakran használják őket, amikor a felhasználói bemenetet egy adott típusra konvertálják, vagy egy típust jelenítenek meg a felhasználónak. Ezek a felületek a System névtérben találhatók.
| Interfész neve | Leírás |
|---|---|
| IParsable<TSelf> | Elérhetővé teszi a T.Parse(string, IFormatProvider) és T.TryParse(string, IFormatProvider, out TSelf) támogatását. |
| ISpanParsable<TSelf> | Elérhetővé teszi a T.Parse(ReadOnlySpan<char>, IFormatProvider) és T.TryParse(ReadOnlySpan<char>, IFormatProvider, out TSelf) támogatását. |
| IFormattable 1 | Támogatást biztosít a következőhöz: value.ToString(string, IFormatProvider). |
| ISpanFormattable 1 | Támogatást biztosít a következőhöz: value.TryFormat(Span<char>, out int, ReadOnlySpan<char>, IFormatProvider). |
1Ez a felület nem új, és nem is általános. Azonban minden számtípus a függvény inverz műveletének implementációját képviseli, amelyet IParsable jelöl.
A következő program például két számot vesz fel bemenetként, és egy általános módszerrel olvassa be őket a konzolról, ahol a típusparaméter korlátozott.IParsable<TSelf> Az átlagot egy általános módszerrel számítja ki, amelyben a bemeneti és eredményértékek típusparaméterei korlátozottak, INumber<TSelf>majd megjeleníti az eredményt a konzolon.
using System.Globalization;
using System.Numerics;
static TResult Average<T, TResult>(T first, T second)
where T : INumber<T>
where TResult : INumber<TResult>
{
return TResult.CreateChecked( (first + second) / T.CreateChecked(2) );
}
static T ParseInvariant<T>(string s)
where T : IParsable<T>
{
return T.Parse(s, CultureInfo.InvariantCulture);
}
Console.Write("First number: ");
var left = ParseInvariant<float>(Console.ReadLine());
Console.Write("Second number: ");
var right = ParseInvariant<float>(Console.ReadLine());
Console.WriteLine($"Result: {Average<float, float>(left, right)}");
/* This code displays output similar to:
First number: 5.0
Second number: 6
Result: 5.5
*/