Bellergegevens bepalen met behulp van kenmerken die worden geïnterpreteerd door de C#-compiler

Met behulp van infokenmerken verkrijgt u informatie over de aanroeper naar een methode. U verkrijgt het bestandspad van de broncode, het regelnummer in de broncode en de lidnaam van de aanroeper. Als u informatie over ledenoproepen wilt verkrijgen, gebruikt u kenmerken die worden toegepast op optionele parameters. Elke optionele parameter geeft een standaardwaarde op. In de volgende tabel ziet u de kenmerken Van nummerweergave die zijn gedefinieerd in de System.Runtime.CompilerServices naamruimte:

Kenmerk Beschrijving Type
CallerFilePathAttribute Volledig pad van het bronbestand dat de aanroeper bevat. Het volledige pad is het pad tijdens het compileren. String
CallerLineNumberAttribute Regelnummer in het bronbestand waaruit de methode wordt aangeroepen. Integer
CallerMemberNameAttribute Methodenaam of eigenschapsnaam van de aanroeper. String
CallerArgumentExpressionAttribute Tekenreeksweergave van de argumentexpressie. String

Deze informatie helpt u bij het traceren en opsporen van fouten en helpt u bij het maken van diagnostische hulpprogramma's. In het volgende voorbeeld ziet u hoe u kenmerken van aanroepergegevens gebruikt. Bij elke aanroep naar de TraceMessage methode wordt de aanroepergegevens ingevoegd voor de argumenten voor de optionele parameters.

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

U geeft een expliciete standaardwaarde op voor elke optionele parameter. U kunt geen kenmerken van aanroepergegevens toepassen op parameters die niet als optioneel zijn opgegeven. De gegevenskenmerken van de aanroeper maken geen parameter optioneel. In plaats daarvan hebben ze invloed op de standaardwaarde die wordt doorgegeven wanneer het argument wordt weggelaten. De gegevenswaarden van de beller worden tijdens het compileren verzonden als letterlijke waarden in de Tussenliggende taal (IL). In tegenstelling tot de resultaten van de StackTrace eigenschap voor uitzonderingen, worden de resultaten niet beïnvloed door verdoezeling. U kunt expliciet de optionele argumenten opgeven om de gegevens van de beller te beheren of om aanroepergegevens te verbergen.

Ledennamen

U kunt het CallerMemberName kenmerk gebruiken om te voorkomen dat u de lidnaam opgeeft als argument String voor de aangeroepen methode. Door deze techniek te gebruiken, voorkomt u het probleem dat herstructureren de waarden niet wijzigt String . Dit voordeel is vooral handig voor de volgende taken:

  • Tracering en diagnostische routines gebruiken.
  • INotifyPropertyChanged De interface implementeren bij het binden van gegevens. Met deze interface kan de eigenschap van een object een afhankelijk besturingselement melden dat de eigenschap is gewijzigd. Het besturingselement kan de bijgewerkte informatie weergeven. Zonder het CallerMemberName kenmerk moet u de naam van de eigenschap opgeven als een letterlijke waarde.

In de volgende grafiek ziet u de ledennamen die worden geretourneerd wanneer u het CallerMemberName kenmerk gebruikt.

Aanroepen vinden plaats binnen Resultaat van lidnaam
Methode, eigenschap of gebeurtenis De naam van de methode, eigenschap of gebeurtenis waaruit de aanroep afkomstig is.
Constructor De tekenreeks ".ctor"
Statische constructor De tekenreeks '.cctor'
Finalizer De tekenreeks 'Finalize'
Door de gebruiker gedefinieerde operators of conversies De gegenereerde naam voor het lid, bijvoorbeeld 'op_Addition'.
Kenmerkconstructor De naam van de methode of eigenschap waarop het kenmerk wordt toegepast. Als het kenmerk een element binnen een lid is (zoals een parameter, een retourwaarde of een algemene typeparameter), is dit resultaat de naam van het lid dat aan dat element is gekoppeld.
Geen lid (bijvoorbeeld assemblyniveau of kenmerken die worden toegepast op typen) De standaardwaarde van de optionele parameter.

Argumentexpressies

U gebruikt de System.Runtime.CompilerServices.CallerArgumentExpressionAttribute expressie wanneer u wilt dat de expressie als argument wordt doorgegeven. Diagnostische bibliotheken willen mogelijk meer informatie geven over de expressies die worden doorgegeven aan argumenten. Door de expressie op te geven die de diagnose heeft geactiveerd, hebben ontwikkelaars naast de parameternaam meer informatie over de voorwaarde die de diagnose heeft geactiveerd. Deze extra informatie maakt het gemakkelijker om dit op te lossen.

In het volgende voorbeeld ziet u hoe u gedetailleerde informatie over het argument kunt opgeven wanneer het ongeldig is:

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

U zou deze aanroepen zoals wordt weergegeven in het volgende voorbeeld:

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

De expressie waarvoor wordt gebruikt condition , wordt door de compiler in het message argument geïnjecteerd. Wanneer een ontwikkelaar een null argument aanroeptOperation, wordt het volgende bericht opgeslagen in:ArgumentException

Argument failed validation: <func is not null>

Met dit kenmerk kunt u diagnostische hulpprogramma's schrijven die meer informatie bieden. Ontwikkelaars kunnen sneller begrijpen welke wijzigingen nodig zijn. U kunt ook de CallerArgumentExpressionAttribute expressie gebruiken om te bepalen welke expressie is gebruikt als ontvanger voor extensiemethoden. Met de volgende methode wordt een reeks met regelmatige tussenpozen gebruikt. Als de reeks minder elementen heeft dan de frequentie, wordt er een fout gerapporteerd:

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;
    }
}

In het vorige voorbeeld wordt de nameof operator voor de parameter sequencegebruikt. Deze functie is beschikbaar in C# 11. Voor C# 11 moet u de naam van de parameter als tekenreeks typen. U kunt deze methode als volgt aanroepen:

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

In het voorgaande voorbeeld wordt een ArgumentException bericht met de volgende tekst weergegeven:

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

Zie ook