Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C# generic method detect if T is array and then index into the array

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 anobject[], I get ‘((object[])((object)thingToLog))[0]’ threw an exception of type ‘System.InvalidCastException’`

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Is it possible to detect if T is enumerable, and if so enumerate the elements for printing?

>Solution :

To solve this problem, you can use reflection to handle different types of collections and arrays. I have provided the updated version of your ‘Dbg’ function which can properly handle arrays and other enumerable types.

using System;
using System.Collections;
using System.Linq;
using System.Runtime.CompilerServices;

public static class Utils
{
public static T Dbg<T>(
    T thingToLog,
    [CallerFilePath] string filepath = null,
    [CallerLineNumber] int lineNumber = 0,
    [CallerMemberName] string caller = null
)
{
    if (System.Diagnostics.Debugger.IsAttached)
    {
        string filename = filepath.Split('\\').Last();
        string stringToLog;

        if (thingToLog is IEnumerable enumerable && !(thingToLog is string))
        {
            var elements = enumerable.Cast<object>().Select(e => e?.ToString() ?? "null");
            stringToLog = "[ " + string.Join(", ", elements) + " ]";
        }
        else
        {
            stringToLog = thingToLog?.ToString() ?? "null";
        }

        Console.WriteLine($"[{filename}:{lineNumber} {caller}()] {stringToLog}");
    }
    return thingToLog;
}
}

Hope this will help

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading