Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Korzystając z atrybutów informacji, uzyskujesz informacje o obiekcie wywołującym metodę. Uzyskujesz ścieżkę pliku kodu źródłowego, numer wiersza w kodzie źródłowym i nazwę elementu członkowskiego obiektu wywołującego. Aby uzyskać informacje o wywołującym członku, należy użyć atrybutów, które są oparte na parametrach opcjonalnych. Każdy opcjonalny parametr określa wartość domyślną. W poniższej tabeli wymieniono atrybuty "Informacje o wywołującym" zdefiniowane w przestrzeni nazw System.Runtime.CompilerServices.
| Attribute | Opis | Typ |
|---|---|---|
| CallerFilePathAttribute | Pełna ścieżka pliku źródłowego zawierającego obiekt wywołujący. Pełna ścieżka to ścieżka w czasie kompilacji. | String |
| CallerLineNumberAttribute | Numer wiersza w pliku źródłowym, z którego jest wywoływana metoda. | Integer |
| CallerMemberNameAttribute | Nazwa metody lub nazwa właściwości obiektu wywołującego. | String |
| CallerArgumentExpressionAttribute | Reprezentacja ciągu wyrażenia argumentu. | String |
Te informacje ułatwiają śledzenie i debugowanie oraz ułatwia tworzenie narzędzi diagnostycznych. W poniższym przykładzie pokazano, jak używać atrybutów informacji o obiekcie wywołującym. Na każdym wywołaniu TraceMessage metody informacje wywołujące są wstawione dla argumentów do parametrów opcjonalnych.
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
Należy określić jawną wartość domyślną dla każdego opcjonalnego parametru. Nie można zastosować atrybutów informacji wywołujących do parametrów, które nie są określone jako opcjonalne. Atrybuty informacji o obiekcie wywołującym nie są opcjonalne. Zamiast tego mają wpływ na wartość domyślną przekazywaną, gdy argument zostanie pominięty. Wartości informacji o obiekcie wywołującym są emitowane jako literały do języka pośredniego (IL) w czasie kompilacji. W przeciwieństwie do wyników StackTrace właściwości wyjątków, zaciemnianie nie wpływa na wyniki. Możesz jawnie podać opcjonalne argumenty, aby kontrolować informacje o obiekcie wywołującym lub ukrywać informacje o obiekcie wywołującym.
Nazwy elementów członkowskich
Możesz użyć atrybutu CallerMemberName, aby uniknąć określania nazwy składowej jako argumentu String do wywoływanej metody. Korzystając z tej techniki, unikniesz problemu, że Refaktoryzacja Zmiany Nazwy nie zmienia String wartości. Ta korzyść jest szczególnie przydatna w następujących zadaniach:
- Korzystanie z procedur śledzenia i diagnostyki.
- Implementowanie interfejsu INotifyPropertyChanged podczas wiązania danych. Ten interfejs umożliwia właściwości obiektu powiadamianie powiązanej kontrolki o zmianie właściwości. Kontrolka może wyświetlać zaktualizowane informacje. Jeśli nie ma atrybutu
CallerMemberName, należy podać nazwę właściwości jako literał.
Na poniższym wykresie przedstawiono nazwy członków zwracane podczas używania atrybutu CallerMemberName.
| Wywołania występują w obrębie | Rezultat związany z nazwą członka |
|---|---|
| Metoda, właściwość lub zdarzenie | Nazwa metody, właściwości lub zdarzenia, z którego pochodzi wywołanie. |
| Konstruktor | Ciąg ".ctor" |
| Konstruktor statyczny | Ciąg ".cctor" |
| Finalizator | Ciąg "Finalizuj" |
| Operatory lub konwersje zdefiniowane przez użytkownika | Wygenerowana nazwa dla członka, na przykład "op_Addition". |
| Konstruktor atrybutu | Nazwa metody lub właściwości, do której jest stosowany atrybut. Jeśli atrybut jest dowolnym elementem w elemencie członkowskim (takim jak parametr, wartość zwracana lub parametr typu ogólnego), ten wynik jest nazwą elementu członkowskiego skojarzonego z tym elementem. |
| Brak członka zawierającego (na przykład na poziomie zestawu assembly lub atrybutów stosowanych do typów) | Wartość domyślna opcjonalnego parametru. |
Wyrażenia argumentów
System.Runtime.CompilerServices.CallerArgumentExpressionAttribute W przypadku, gdy chcesz, aby wyrażenie było przekazywane jako argument. Biblioteki diagnostyczne mogą udostępniać więcej szczegółów na temat wyrażeń przekazywanych do argumentów. Podając wyrażenie, które wyzwoliło diagnostykę, oprócz nazwy parametru, deweloperzy mają więcej szczegółów na temat warunku, który wyzwolił diagnostykę. Te dodatkowe informacje ułatwiają naprawienie.
W poniższym przykładzie pokazano, jak można podać szczegółowe informacje o argumencie, gdy jest on nieprawidłowy:
public static void ValidateArgument(string parameterName, bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
if (!condition)
{
throw new ArgumentException($"Argument failed validation: <{message}>", parameterName);
}
}
Wywołasz go, jak pokazano w poniższym przykładzie:
public void Operation(Action func)
{
Utilities.ValidateArgument(nameof(func), func is not null);
func();
}
Kompilator wprowadza wyrażenie używane do condition argumentu message . Gdy deweloper wywołuje Operation argument z argumentem null , następujący komunikat jest przechowywany w pliku ArgumentException:
Argument failed validation: <func is not null>
Ten atrybut umożliwia pisanie narzędzi diagnostycznych, które zawierają więcej szczegółów. Deweloperzy mogą szybciej zrozumieć, jakie zmiany są potrzebne. Można również użyć elementu , CallerArgumentExpressionAttribute aby określić, które wyrażenie zostało użyte jako odbiornik dla składowych rozszerzeń. Poniższa metoda próbkuje sekwencję w regularnych odstępach czasu. Jeśli sekwencja ma mniej elementów niż częstotliwość, zgłasza błąd:
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;
}
}
}
W poprzednim przykładzie użyto nameof operatora dla parametru sequence. Tę metodę można wywołać w następujący sposób:
sample = Enumerable.Range(0, 10).Sample(100);
W powyższym przykładzie zostanie zgłoszony ArgumentException komunikat, którego wiadomość jest następującym tekstem:
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')