A hívó adatainak meghatározása a C# fordító által értelmezett attribútumokkal
Az infoattribútumok használatával adatokat szerezhet be a hívóról egy metódushoz. Beolvashatja a forráskód elérési útját, a forráskód sorszámát és a hívó tagnevét. A taghívó adatainak lekéréséhez az opcionális paraméterekre alkalmazott attribútumokat kell használnia. Minden választható paraméter egy alapértelmezett értéket ad meg. Az alábbi táblázat a névtérben System.Runtime.CompilerServices definiált hívóinformációs attribútumokat sorolja fel:
Attribútum | Leírás | Típus |
---|---|---|
CallerFilePathAttribute | A hívót tartalmazó forrásfájl teljes elérési útja. A teljes elérési út a fordítási időpontban megadott elérési út. | String |
CallerLineNumberAttribute | Annak a forrásfájlnak a sorszáma, amelyből a metódust meghívják. | Integer |
CallerMemberNameAttribute | A hívó metódusneve vagy tulajdonságneve. | String |
CallerArgumentExpressionAttribute | Az argumentumkifejezés sztring-ábrázolása. | String |
Ezek az információk segítenek a nyomkövetésben és a hibakeresésben, és segítenek diagnosztikai eszközök létrehozásában. Az alábbi példa bemutatja, hogyan használhat hívóinformációs attribútumokat. A metódus minden egyes hívása TraceMessage
esetén a rendszer beszúrja a hívó adatait az opcionális paraméterek argumentumaihoz.
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
Minden választható paraméterhez explicit alapértelmezett értéket kell megadnia. Nem alkalmazhat hívóinformációs attribútumokat a nem kötelezőként megadott paraméterekre. A hívó információattribútumai nem teszik kötelezővé a paramétert. Ehelyett az argumentum kihagyásakor átadott alapértelmezett értéket befolyásolják. A hívóinformációs értékek fordításkor literálként lesznek kibocsátva a köztes nyelvbe (IL). A kivételek tulajdonságának StackTrace eredményeivel ellentétben az eredményeket nem befolyásolja az elfedés. Explicit módon megadhatja az opcionális argumentumokat a hívó információinak szabályozásához vagy a hívó adatainak elrejtéséhez.
Tagnevek
Az attribútum használatával elkerülheti, CallerMemberName
hogy a tag nevét argumentumként String
adja meg a hívott metódushoz. Ezzel a technikával elkerülheti azt a problémát, hogy az újrabontás átnevezése nem módosítja az String
értékeket. Ez az előny különösen hasznos a következő feladatokhoz:
- Nyomkövetési és diagnosztikai rutinok használata.
- Az interfész implementálása adatok INotifyPropertyChanged kötésekor. Ez a felület lehetővé teszi, hogy egy objektum tulajdonsága értesítse a kötött vezérlőt arról, hogy a tulajdonság megváltozott. A vezérlő megjelenítheti a frissített információkat. Az
CallerMemberName
attribútum nélkül a tulajdonság nevét literálként kell megadnia.
Az alábbi diagram az attribútum használatakor CallerMemberName
visszaadott tagneveket mutatja.
A hívások a | Tagnév eredménye |
---|---|
Metódus, tulajdonság vagy esemény | Annak a metódusnak, tulajdonságnak vagy eseménynek a neve, amelyből a hívás származik. |
Konstruktor | A ".ctor" sztring |
Statikus konstruktor | A ".cctor" sztring |
Finalizer | A "Véglegesítés" sztring |
Felhasználó által definiált operátorok vagy konverziók | A tag generált neve, például "op_Addition". |
Attribútumkonstruktor | Annak a metódusnak vagy tulajdonságnak a neve, amelyre az attribútumot alkalmazza. Ha az attribútum egy tag bármely eleme (például paraméter, visszatérési érték vagy általános típusparaméter), ez az eredmény annak a tagnak a neve, amely az adott elemhez van társítva. |
Nem tartalmaz tagot (például szerelvényszintű vagy típusokra alkalmazott attribútumokat) | Az opcionális paraméter alapértelmezett értéke. |
Argumentumkifejezések
A kifejezést akkor használja System.Runtime.CompilerServices.CallerArgumentExpressionAttribute , ha argumentumként szeretné átadni a kifejezést. Előfordulhat, hogy a diagnosztikai kódtárak további részleteket szeretnének megadni az argumentumoknak átadott kifejezésekről. A diagnosztika kiváltó kifejezésének megadásával a paraméternév mellett a fejlesztők további részleteket is megtudhatnak a diagnosztika kiváltó feltételéről. Ez a további információ megkönnyíti a javítást.
Az alábbi példa bemutatja, hogyan adhat meg részletes információkat az argumentumról, ha érvénytelen:
public static void ValidateArgument(string parameterName, bool condition, [CallerArgumentExpression("condition")] string? message=null)
{
if (!condition)
{
throw new ArgumentException($"Argument failed validation: <{message}>", parameterName);
}
}
A következő példában látható módon hívná meg:
public void Operation(Action func)
{
Utilities.ValidateArgument(nameof(func), func is not null);
func();
}
A használt condition
kifejezést a fordító injektálja az message
argumentumba. Amikor egy fejlesztő argumentummal null
hívOperation
, a rendszer a következő üzenetet tárolja a ArgumentException
következő helyen:
Argument failed validation: <func is not null>
Ez az attribútum lehetővé teszi olyan diagnosztikai segédprogramok írását, amelyek további részleteket nyújtanak. A fejlesztők gyorsabban megérthetik, hogy milyen módosításokra van szükség. A bővítménymetelyek fogadójaként használt kifejezés meghatározására is használható CallerArgumentExpressionAttribute . Az alábbi módszer rendszeres időközönként mintát vesz egy sorozatból. Ha a sorozat kevesebb elemből áll, mint a gyakoriság, hibát jelez:
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;
}
}
Az előző példa az operátort nameof
használja a paraméterhez sequence
. Ez a funkció a C# 11-ben érhető el. A C# 11 előtt sztringként kell beírnia a paraméter nevét. Ezt a metódust a következőképpen hívhatja meg:
sample = Enumerable.Range(0, 10).Sample(100);
Az előző példa egy ArgumentException olyan üzenetet jelenít meg, amelynek üzenete a következő:
Expression doesn't have enough elements: Enumerable.Range(0, 10) (Parameter 'sequence')