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 o volajícím člena, použijte atributy, které jsou použity 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ů:
Atribut | Popis | Typ |
---|---|---|
CallerFilePathAttribute | Úplná cesta zdrojového 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 mají vliv na výchozí hodnotu, která je předána, pokud je argument vynechán. 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 nejsou výsledky ovlivněny obfuskací. Volitelné argumenty můžete explicitně zadat, chcete-li řídit nebo skrýt informace o volajícím.
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, který refaktoring pro přejmenování nezmění String
hodnoty. Tato výhoda se hodí zvláště v těchto úlohách:
- Použití trasování a diagnostických rutin.
- INotifyPropertyChanged Implementace rozhraní při vytváření vazeb 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ýsledek názvu členu |
---|---|
Metoda, vlastnost nebo událost | Název metody, vlastnosti nebo události, z nichž bylo volání provedeno. |
Konstruktor | Řetězec „.ctor“ |
Statický konstruktor | Řetězec „.cctor“ |
Finalizátor | Řetězec „Finalize“ |
Operátory nebo převody definované uživatelem | Vygenerovaný název pro člen, například „op_Addition“. |
Konstruktor atributu | Název metody nebo vlastnosti, na kterou je atribut použit. Pokud je atribut libovolný prvek v členu (například parametr, návratová hodnota nebo parametr obecného typu), je tento výsledek názvem členu, který je přidružen k tomuto prvku. |
Žádný obsahující člen (například úroveň sestavení nebo atributy, které jsou použity 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 chtít poskytnout 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();
}
Výraz použitý pro condition
je vložen kompilátorem do argumentu message
. Když vývojář zavolá Operation
s argumentem null
, uloží se ArgumentException
v 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 rozšiřující metody. Následující metoda v pravidelných intervalech vzorkuje posloupnost. Pokud má sekvence méně prvků, než je frekvence, hlásí chybu:
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;
}
}
Předchozí příklad používá nameof
operátor pro parametr sequence
. Tato funkce je dostupná v jazyce C# 11. Před C# 11 budete muset zadat název parametru jako řetězec. 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')