Megosztás a következőn keresztül:


A hívó adatainak meghatározása a C# fordító által értelmezett attribútumokkal

Az infoattribútumok használatával adatokat szerezhet be a hívóról egy metódushoz. Beolvashatja a forráskód elérési útját, a forráskód sorszámát és a hívó tagnevét. A taghívó adatainak lekéréséhez az opcionális paraméterekre alkalmazott attribútumokat kell használnia. Minden választható paraméter egy alapértelmezett értéket ad meg. Az alábbi táblázat a névtérben System.Runtime.CompilerServices definiált hívóinformációs attribútumokat sorolja fel:

Attribútum Leírás Típus
CallerFilePathAttribute A hívót tartalmazó forrásfájl teljes elérési útja. A teljes elérési út a fordítási időpontban megadott elérési út. String
CallerLineNumberAttribute Annak a forrásfájlnak a sorszáma, amelyből a metódust meghívják. Integer
CallerMemberNameAttribute A hívó metódusneve vagy tulajdonságneve. String
CallerArgumentExpressionAttribute Az argumentumkifejezés sztring-ábrázolása. String

Ezek az információk segítenek a nyomkövetésben és a hibakeresésben, és segítenek diagnosztikai eszközök létrehozásában. Az alábbi példa bemutatja, hogyan használhat hívóinformációs attribútumokat. A metódus minden egyes hívása TraceMessage esetén a rendszer beszúrja a hívó adatait az opcionális paraméterek argumentumaihoz.

public void DoProcessing()
{
    TraceMessage("Something happened.");
}

public void TraceMessage(string message,
        [CallerMemberName] string memberName = "",
        [CallerFilePath] string sourceFilePath = "",
        [CallerLineNumber] int sourceLineNumber = 0)
{
    Trace.WriteLine("message: " + message);
    Trace.WriteLine("member name: " + memberName);
    Trace.WriteLine("source file path: " + sourceFilePath);
    Trace.WriteLine("source line number: " + sourceLineNumber);
}

// Sample Output:
//  message: Something happened.
//  member name: DoProcessing
//  source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
//  source line number: 31

Minden választható paraméterhez explicit alapértelmezett értéket kell megadnia. Nem alkalmazhat hívóinformációs attribútumokat a nem kötelezőként megadott paraméterekre. A hívó információattribútumai nem teszik kötelezővé a paramétert. Ehelyett az argumentum kihagyásakor átadott alapértelmezett értéket befolyásolják. A hívóinformációs értékek fordításkor literálként lesznek kibocsátva a köztes nyelvbe (IL). A kivételek tulajdonságának StackTrace eredményeivel ellentétben az eredményeket nem befolyásolja az elfedés. Explicit módon megadhatja az opcionális argumentumokat a hívó információinak szabályozásához vagy a hívó adatainak elrejtéséhez.

Tagnevek

Az attribútum használatával elkerülheti, CallerMemberName hogy a tag nevét argumentumként String adja meg a hívott metódushoz. Ezzel a technikával elkerülheti azt a problémát, hogy az újrabontás átnevezése nem módosítja az String értékeket. Ez az előny különösen hasznos a következő feladatokhoz:

  • Nyomkövetési és diagnosztikai rutinok használata.
  • Az interfész implementálása adatok INotifyPropertyChanged kötésekor. Ez a felület lehetővé teszi, hogy egy objektum tulajdonsága értesítse a kötött vezérlőt arról, hogy a tulajdonság megváltozott. A vezérlő megjelenítheti a frissített információkat. Az CallerMemberName attribútum nélkül a tulajdonság nevét literálként kell megadnia.

Az alábbi diagram az attribútum használatakor CallerMemberName visszaadott tagneveket mutatja.

A hívások a Tagnév eredménye
Metódus, tulajdonság vagy esemény Annak a metódusnak, tulajdonságnak vagy eseménynek a neve, amelyből a hívás származik.
Konstruktor A ".ctor" sztring
Statikus konstruktor A ".cctor" sztring
Finalizer A "Véglegesítés" sztring
Felhasználó által definiált operátorok vagy konverziók A tag generált neve, például "op_Addition".
Attribútumkonstruktor Annak a metódusnak vagy tulajdonságnak a neve, amelyre az attribútumot alkalmazza. Ha az attribútum egy tag bármely eleme (például paraméter, visszatérési érték vagy általános típusparaméter), ez az eredmény annak a tagnak a neve, amely az adott elemhez van társítva.
Nem tartalmaz tagot (például szerelvényszintű vagy típusokra alkalmazott attribútumokat) Az opcionális paraméter alapértelmezett értéke.

Argumentumkifejezések

A kifejezést akkor használja System.Runtime.CompilerServices.CallerArgumentExpressionAttribute , ha argumentumként szeretné átadni a kifejezést. Előfordulhat, hogy a diagnosztikai kódtárak további részleteket szeretnének megadni az argumentumoknak átadott kifejezésekről. A diagnosztika kiváltó kifejezésének megadásával a paraméternév mellett a fejlesztők további részleteket is megtudhatnak a diagnosztika kiváltó feltételéről. Ez a további információ megkönnyíti a javítást.

Az alábbi példa bemutatja, hogyan adhat meg részletes információkat az argumentumról, ha érvénytelen:

public static void ValidateArgument(string parameterName, bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
    if (!condition)
    {
        throw new ArgumentException($"Argument failed validation: <{message}>", parameterName);
    }
}

A következő példában látható módon hívná meg:

public void Operation(Action func)
{
    Utilities.ValidateArgument(nameof(func), func is not null);
    func();
}

A használt condition kifejezést a fordító injektálja az message argumentumba. Amikor egy fejlesztő argumentummal null hívOperation, a rendszer a következő üzenetet tárolja a ArgumentExceptionkövetkező helyen:

Argument failed validation: <func is not null>

Ez az attribútum lehetővé teszi olyan diagnosztikai segédprogramok írását, amelyek további részleteket nyújtanak. A fejlesztők gyorsabban megérthetik, hogy milyen módosításokra van szükség. A bővítménymetelyek fogadójaként használt kifejezés meghatározására is használható CallerArgumentExpressionAttribute . Az alábbi módszer rendszeres időközönként mintát vesz egy sorozatból. Ha a sorozat kevesebb elemből áll, mint a gyakoriság, hibát jelez:

public static IEnumerable<T> Sample<T>(this IEnumerable<T> sequence, int frequency, 
    [CallerArgumentExpression(nameof(sequence))] string? message = null)
{
    if (sequence.Count() < frequency)
        throw new ArgumentException($"Expression doesn't have enough elements: {message}", nameof(sequence));
    int i = 0;
    foreach (T item in sequence)
    {
        if (i++ % frequency == 0)
            yield return item;
    }
}

Az előző példa az operátort nameof használja a paraméterhez sequence. Ez a funkció a C# 11-ben érhető el. A C# 11 előtt sztringként kell beírnia a paraméter nevét. Ezt a metódust a következőképpen hívhatja meg:

sample = Enumerable.Range(0, 10).Sample(100);

Az előző példa egy ArgumentException olyan üzenetet jelenít meg, amelynek üzenete a következő:

Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')

Lásd még