I'm trying to write a Dbg
debug function that will print out some debug info about the given parameter and then return it. I would like arrays to be printed as the list of elements, and scalars to just be printed using .ToString()
. So far I've got:
public static class Utils
{
/// <summary>
/// Log the given expression to the console iff a debugger is attached,
/// returning that same value transparently. Useful for debugging values
/// without rewriting all your code. Also logs the caller and line
/// number via compiler trickery.
/// </summary>
public static T Dbg<T>(
T thingToLog,
// Ask the compiler to insert the current file, line number, and caller
[CallerFilePathAttribute] string filepath = null,
[CallerLineNumber] int lineNumber = 0,
[CallerMemberName] string caller = null
)
{
if (System.Diagnostics.Debugger.IsAttached)
{
string filename = filepath.Split('\\').Last();
// FIXME This doesn't actually print the array, just "System.Byte[]" or similar
string stringToLog = typeof(T).IsArray ? "[ " + String.Join(", ", thingToLog) + " ]" : thingToLog.ToString();
Console.WriteLine($"[{filename}:{lineNumber} {caller}()] {stringToLog}");
}
return thingToLog;
}
}
The problem is this line:
string stringToLog = typeof(T).IsArray ? "[ " + String.Join(", ", thingToLog) + " ]" : thingToLog.ToString();
which just outputs the type of thingToLog
, like System.Byte[]
, but I want it to output the elements in the byte array. In the debugger, trying to access an element of thingToLog
results in thingToLog[0] error CS0021: Cannot apply indexing with [] to an expression of type 'T'
, fair enough. But if I try to cast to an object[]
, then I get ((object[])thingToLog)[0] error CS0030: Cannot convert type 'T' to 'object[]'. And if I try first cast to an
objectand then to an
object[], I get
'((object[])((object)thingToLog))[0]' threw an exception of type 'System.InvalidCastException'`
Is it possible to detect if T
is enumerable, and if so enumerate the elements for printing?
T
is an array? You can just checkis IEnumerable
for that. If you actually want to check for arrays, do you also want to check for 2-(or more) dimensional arrays? In that case, you cannot only use one single integer as the index.