Rezervované atributy: určení informací o volajícím
Pomocí atributů info získáte informace o volajícím metody. Získáte cestu k souboru zdrojového kódu, číslo řádku ve zdrojovém kódu a název členu volajícího. Chcete-li získat informace o volajícím členu, použijte atributy, které se použijí na volitelné parametry. Každý volitelný parametr určuje výchozí hodnotu. V následující tabulce jsou uvedeny atributy informací 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 metoda volána. | 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í s vytvářením diagnostických nástrojů. Následující příklad ukazuje, jak použít atributy informace o volajícím. Při každém volání TraceMessage metody jsou pro argumenty pro volitelné parametry vloženy informace o volajícím.
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 nelze použít u parametrů, které nejsou zadány jako volitelné. Atributy informace o volajícím nevytvářejí 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 jsou generovány jako literály do mezilehlého jazyka (IL) v době kompilace. Na rozdíl od výsledků StackTrace vlastnosti pro výjimky nejsou výsledky ovlivněny zmatením. Volitelné argumenty můžete explicitně zadat, chcete-li řídit nebo skrýt informace o volajícím.
Názvy členů
Atribut lze použít CallerMemberName k zamezení zadání názvu člena jako String argumentu volané metody. Pomocí této techniky se vyhnete problému s tím, že Refaktoring přejmenování hodnoty nemění String . Tato výhoda se hodí zvláště v těchto úlohách:
- Použití trasování a diagnostických rutin.
- Implementace INotifyPropertyChanged rozhraní při vázání dat. Toto rozhraní umožňuje vlastnosti objektu informovat vázaný ovládací prvek, že došlo ke změně vlastnosti. Ovládací prvek může zobrazit aktualizované informace. Bez
CallerMemberNameatributu je nutné zadat název vlastnosti jako literál.
Následující graf znázorňuje názvy členů, které jsou vráceny při použití CallerMemberName atributu.
| K volání dochází 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“ |
| Finalizační metodu | Ř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žijte, pokud chcete, aby byl System.Runtime.CompilerServices.CallerArgumentExpressionAttribute výraz předán jako argument. Knihovny diagnostiky můžou poskytnout další podrobnosti o výrazech předaných argumentům. Poskytnutím výrazu, který aktivoval diagnostiku, kromě názvu parametru mají vývojáři další podrobnosti o stavu, který diagnostiku aktivoval. Tyto další informace usnadňují opravu.
Následující příklad ukazuje, jak můžete zadat podrobné informace o argumentu, pokud 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 message argumentu. Pokud vývojář volá Operation s null argumentem, je následující zpráva uložena v ArgumentException :
Argument failed validation: <func is not null>
Tento atribut umožňuje napsat diagnostické nástroje, které poskytují další podrobnosti. Vývojáři můžou rychleji pochopit, jaké změny potřebujete. Můžete také použít CallerArgumentExpressionAttribute k určení, který výraz byl použit jako přijímač pro metody rozšíření. Následující metoda vzorkuje sekvenci v pravidelných intervalech. Pokud má sekvence méně prvků než frekvence, ohlásí chybu:
public static IEnumerable<T> Sample<T>(this IEnumerable<T> sequence, int frequency,
[CallerArgumentExpression("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;
}
}
Tuto metodu můžete zavolat následujícím způsobem:
sample = Enumerable.Range(0, 10).Sample(100);
Předchozí příklad by vyvolal ArgumentException , jehož zpráva je následující text:
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')