Sdílet prostřednictvím


Určení informací volajícího pomocí atributů interpretovaných kompilátorem jazyka C#

Pomocí atributů informací získáte informace o volající metodě. Získáte cestu k souboru zdrojového kódu, číslo řádku ve zdrojovém kódu a název člena volajícího. Chcete-li získat informace volajícího člena, použijte atributy, které se aplikují na volitelné parametry. Každý volitelný parametr určuje výchozí hodnotu. 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 zadané jako 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. Hodnoty informací o volajícím se v době kompilace vygenerují jako literály do jazyka IL (Intermediate Language). 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ů

Atribut můžete použít CallerMemberName k tomu, abyste zabránili zadání názvu člena jako argumentu 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ů

Použijete System.Runtime.CompilerServices.CallerArgumentExpressionAttribute , 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>

Tento atribut umožňuje psát 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);

V předchozím příkladu by se zobrazila zpráva s následujícím textem ArgumentException :

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

Viz také