Sdílet prostřednictvím


Určení informací volajícího pomocí atributů, které kompilátor jazyka C# interpretuje

Pomocí atributů informací můžete získat informace o volající metodě. Můžete získat cestu k souboru zdrojového kódu, číslo řádku ve zdrojovém kódu a název člena volajícího. Pokud chcete získat informace o volajícím člena, použijte atributy, které použijete na volitelné parametry. Každý volitelný parametr určuje výchozí hodnotu.

Referenční dokumentace jazyka C# dokumentuje naposledy vydané verze jazyka C#. Obsahuje také počáteční dokumentaci k funkcím ve verzi Public Preview pro nadcházející jazykovou verzi.

Dokumentace identifikuje všechny funkce, které byly poprvé představeny v posledních třech verzích jazyka nebo v aktuálních verzích Public Preview.

Návod

Informace o tom, kdy byla funkce poprvé představena v jazyce C#, najdete v článku o historii verzí jazyka C#.

Následující tabulka uvádí atributy Informace o volajícím, které jsou definovány v System.Runtime.CompilerServices oboru názvů:

Vlastnost Popis Typ
CallerFilePathAttribute Úplná cesta ke zdrojovému souboru, který obsahuje volajícího. Úplná cesta je cesta v době kompilace. String
CallerLineNumberAttribute Číslo řádku ve zdrojovém souboru, ze kterého je volána metoda. Integer
CallerMemberNameAttribute Název metody nebo název vlastnosti volajícího String
CallerArgumentExpressionAttribute Řetězcová reprezentace výrazu argumentu String

Tyto informace vám pomůžou s trasováním a laděním a pomáhají vytvářet diagnostické nástroje. Následující příklad ukazuje, jak používat atributy informací o volajícím. Při každém volání TraceMessage metody se informace volajícího vloží pro argumenty do volitelných parametrů.

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

Pro každý volitelný parametr zadáte explicitní výchozí hodnotu. Atributy informací o volajícím nemůžete použít u parametrů, které nejsou volitelné. Atributy informací o volajícím nevytvářají parametr jako volitelný. Místo toho ovlivňují výchozí hodnotu předanou při vynechání argumentu. Kompilátor generuje informační hodnoty volajícího jako literály do jazyka IL (Intermediate Language) v době kompilace. Na rozdíl od výsledků StackTrace vlastnosti pro výjimky nemá obfuskace vliv na výsledky. Volitelné argumenty můžete explicitně zadat pro řízení informací volajícího nebo skrytí informací volajícího.

Jména členů

Pomocí atributu CallerMemberName se vyhněte zadání názvu člena jako argument pro volanou String metodu. Pomocí této techniky se vyhnete problému, ve kterém Rename Refactoring nezmění String hodnoty. Tato výhoda je zvlášť užitečná pro následující úlohy:

  • Použití trasovacích a diagnostických rutin
  • Implementace rozhraní INotifyPropertyChanged při vazbě dat. Toto rozhraní umožňuje vlastnost objektu oznámit vázanému ovládacímu prvku, že se vlastnost změnila. Ovládací prvek může zobrazit aktualizované informace. Bez atributu CallerMemberName je nutné zadat název vlastnosti jako literál.

Následující graf ukazuje názvy členů, které se vrátí při použití atributu CallerMemberName .

Volání probíhají v rámci Výsledky jména člena
Metoda, vlastnost nebo událost Název metody, vlastnosti nebo události, ze které volání pochází.
Konstruktor Řetězec ".ctor"
Statický konstruktor Řetězec ".cctor"
Finalizátor Řetězec "Finalize"
Uživatelem definované operátory nebo převody Vygenerovaný název člena, například "op_Addition".
Konstruktor atributů Název metody nebo vlastnosti, na kterou je atribut použit. Pokud je atribut libovolný prvek v rámci členu (například parametr, návratová hodnota nebo parametr obecného typu), tento výsledek je název člena přidruženého k tomuto prvku.
Neobsahuje žádného člena (například atributy na úrovni sestavení nebo ty, které jsou aplikovány na typy) Výchozí hodnota volitelného parametru.

Výrazy argumentů

System.Runtime.CompilerServices.CallerArgumentExpressionAttribute Použijte, když chcete, aby byl výraz předán jako argument. Diagnostické knihovny můžou poskytovat další podrobnosti o výrazech předaných argumentům . Zadáním výrazu, který aktivoval diagnostiku, mají vývojáři kromě názvu parametru další podrobnosti o podmínce, která diagnostiku aktivovala. Tyto dodatečné informace usnadňují opravu.

Následující příklad ukazuje, jak můžete zadat podrobné informace o argumentu, když je neplatný:

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

Vyvoláte ho, jak je znázorněno v následujícím příkladu:

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

Kompilátor vloží do argumentu condition výraz použitý promessage. Když vývojář zavolá Operation s argumentem null , uloží se ArgumentExceptionv následující zprávě:

Argument failed validation: <func is not null>

Pomocí tohoto atributu můžete napsat diagnostické nástroje, které poskytují další podrobnosti. Vývojáři můžou rychleji pochopit, jaké změny jsou potřeba. Můžete také použít k určení výrazu CallerArgumentExpressionAttribute , který byl použit jako příjemce pro členy rozšíření. Následující metoda v pravidelných intervalech vzorkuje posloupnost. Pokud má sekvence méně prvků, než je frekvence, hlásí chybu:

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

Předchozí příklad používá nameof operátor pro parametr sequence. Tuto metodu můžete volat následujícím způsobem:

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

Předchozí příklad vyvolá zprávu s následujícím textem ArgumentException :

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

Viz také