4

I have a collection containing variables I want to print the names of the variable in this collection

screenshot

The method that returns the type is working, I couldn't find the name How can I create a function to do this where it says GetName() below


var collection = new List<object> { b,sb,shrt,ushrt,i,ui,lng,ulng,f,d,dec,c,str,b1,b2,b3,o1,o2,o3,o4,dt };
    

foreach (object item in collection)
{
    
    Console.WriteLine("variable name : "+item.GetName() );
    Console.WriteLine("variable value: "+item);
    Console.WriteLine("variable type : "+ item.GetType().Name);
    Console.WriteLine("***************************** ");
}
Recep Kara
  • 41
  • 4
  • 6
    The collection doesn't contain variables, it contains objects/values. As soon as you add an item to the collection, it doesn't care where it originally came from. If for whatever reason you need to maintain the names, consider using a `Dictionary`. – 41686d6564 stands w. Palestine Aug 13 '22 at 22:47
  • I would like to know why you want to do this? What's the purpose of knowing? – Enigmativity Aug 14 '22 at 00:21

2 Answers2

0

Your code shows iterating a collection of type Object and we know for sure that class Object does have a GetType() method and _doesn't_ have a GetName() method or Name property. But the item in your collection most likely isn't "really" an object, it's some class that (like every class) inherits Object. You seem confident that this unknown class has a Name property but even if the object type of item is completely unknown, you can use System.Reflection to print out the Name if it exists and an error readout if it doesn't.

Wrapping this reflection in an Extension Method is of the easier ways to answer your question:

[...]How can I create a function to do this where it says GetName()

static partial class Extensions
{
    public static string GetName(this object unk)
    {
        Type type = unk.GetType();
        PropertyInfo propertyInfo = type.GetProperty("Name");
        if (propertyInfo == null)
        {
            return $"Error: Type '{type.Name}' does not have a Name property.";
        }
        else
        {
            return $"{propertyInfo.GetValue(unk)}";
        }
    }
}

MOCK

With the extension in place, you can now use the syntax shown in your post.

var collection = new object []
{
    new HasNameA(),
    new HasNameB(),
    new NoNameC(),
};

foreach (object item in collection)
{
    Console.WriteLine("variable name : " + item.GetName());
    Console.WriteLine("variable value: " + item);
    Console.WriteLine("variable type : " + item.GetType().Name);
    Console.WriteLine("***************************** ");
}

console

Where:

class HasNameA
{
    public string Name { get; set; } = "A";
    public object Value { get; set; } = 1;
    public override string ToString() => $"{Value}";
}
class HasNameB
{
    public string Name { get; set; } = "B";
    public object Value { get; set; } = "Hello";
    public override string ToString() => $"{Value}";
}
class NoNameC
{
    public object Value { get; set; } = Math.PI;
    public override string ToString() => $"{Value}";
}
IVSoftware
  • 5,732
  • 2
  • 12
  • 23
0

The list does not contain the variables.

It contains either:

  • the values variable or
  • the references that the variable points to

Please see Value types (C# reference).

What you are trying to achieve is not possible without significant changes to the code.

The best I could do is the following.

Result

b: True, Boolean
sb: , StringBuilder
shrt: 7, Int16

Code

using System.Linq.Expressions;
using System.Text;

bool b = true;
StringBuilder sb = new ();
short shrt = 7;


var l = new List<(string Name,object V)> { Get(() => b), Get(() => sb), Get(() => shrt) };

foreach(var x in l)
    Console.WriteLine($"{x.Name}: {x.V}, {x.V.GetType().Name}" );

static (string Name ,T V) Get<T>(Expression<Func<T>> memberExpression)
{
    // https://stackoverflow.com/questions/2616638/access-the-value-of-a-member-expression
    // with modifications
    MemberExpression expressionBody = (MemberExpression)memberExpression.Body;

    var lambda = Expression.Lambda<Func<T>>(expressionBody);
    var getter = lambda.Compile();
    var v =  getter();

    return (expressionBody.Member.Name, v);
}
tymtam
  • 31,798
  • 8
  • 86
  • 126