Link to home
Start Free TrialLog in
Avatar of ngeniusone
ngeniusone

asked on

iterate (foreach) through a struct and SetValue of field

I have a public static struct that I am using in a project.  I am wanting to iterate through the structs fields and determine the type (string, int, etc.) of the field.  If it is of a particular type and a value that I do not like at that point in my code, I want to be able to change that field's value. Looking at the following code below, Why does the use of my SetValue method call not work? And, more importantly can you provide a working example, please?

In the example the fields never change to "set value test".  I need them to be modified. What is wrong here?

This is ASP.NET 2.0 C#.NET that I am using.

Name _name = new Name();
            _name.familyName = "Smith";
            _name.givenName = "John";

            foreach (FieldInfo fi in _name.GetType().GetFields())
            {
                fi.SetValue(_name, "set value test");
                Console.WriteLine(fi.Name + " = " + (fi.GetValue(_name) ?? "").ToString());
            }  
Avatar of mmarinov
mmarinov

Hi ngeniusone,

The above example is correct and working
i have tested it in a web application like this
        Name _name = new Name();
        _name.familyName = "Smith";
        _name.givenName = "John";

        foreach (FieldInfo fi in _name.GetType().GetFields())
        {
            if (fi.Name.StartsWith("f"))
                fi.SetValue(_name, "set value test");
            Response.Write(fi.Name + " = " + (fi.GetValue(_name) ?? "").ToString());
        }

and is changing the values in the fieldInfo object and also in the _name object
May the above code depends on something else in your solution

Regards
Martin
Avatar of ngeniusone

ASKER

Martin,

Perhaps there is something wrong with the way my struct is built. Per the example, I have this:

using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Collections;
using System.Reflection;

public struct Name
{
   public string familyName;
   public string givenName;
}


I used the response.write method like you did in a .aspx page codebehind and I still do not get the correct set value for the field. Here are my imports:
using System;
using System.Data;
using System.Configuration;
using System.Reflection;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;


What could possibly be the issue?

SO basically all I have is the struct as you see it above which is residing in a class file in the app_code folder and I have a test .aspx page with a code behind page that has the script above (yours) in the page_load method having the imports above.

What am I missing?


You do not missing anything
The example is working to me because i have

Public class Name
{
}

The struct is value type and the class is object type.
That is why the code above is working fine to me with a class and not working with struct.

Can you change the struct with class?

Martin
I would prefer not to.  That is why I posed the question.

There has to be a way to set the value of a struct through a foreach. Perhaps not with reflection but through some other means.

How is this possible?
Ok.

I have found to change the values but i can not be sure if this solution is work for you
check it

protected void Page_Load(object sender, EventArgs e)
    {
        Name _name = new Name();
        _name.familyName = "Smith";
        _name.givenName = "John";

        ValueType vt = _name;

        FieldInfo[] fis = _name.GetType().GetFields();
        for (int i = 0; i < fis.Length; i++)
        {
            FieldInfo fi = fis[i];
            if (_name.GetType().IsValueType)
            {
                fi.SetValue(vt, "set value test");
                fi.SetValue(_name, "Test");
            }
            //Response.Write(fi.Name + " = " + (fi.GetValue(vt) ?? "").ToString() + "<br/>");
        }
        PrintValues(_name);
        _name = SetValues(vt);
        PrintValues(_name);

    }

    private Name SetValues(ValueType vt)
    {
        Name newStructure = new Name();
        newStructure.familyName = (string)vt.GetType().GetField("familyName").GetValue(vt);
        newStructure.givenName = (string)vt.GetType().GetField("givenName").GetValue(vt);

        return newStructure;
    }

    private void PrintValues(Name _name)
    {
        FieldInfo[] fis = _name.GetType().GetFields();
        foreach (FieldInfo fi in _name.GetType().GetFields())
        {
            Response.Write(fi.Name + " = " + (fi.GetValue(_name) ?? "").ToString() + "<br/>");
        }
    }

Martin
Martin,

Thanks for all the hard work on this. After all the research has been done perusing the Net and given your answer above, I don't believe what I want to do can be done using a struct.

So if you would be so kind please assist me in describing why it would be better to use a class rather than a struct in this case.

Here is what I was trying to do with a struct but tell me if it would be better to just use a class and why:
1.) instantiate a struct object
2.) load the struct object fields with values
3.) pass the instantiated struct object to a method (the method has a db connection with params that need values)

4.) HERE's the KICKER...iterate through the argument object fields and determine if the field is a string having a value of NULL. If it is NULL set that field value to anything but NULL like string.empty or "" or "N/A"

5.) then still within the method retrieve the values for each object field (_name.familyName) while setting the respective command object parameter values to that field (ex: param(....).value = _name.familyName;). At this point any string fields that were NULL would have been replaced with an alternate value.

This is going to run in an e-commerce application.  Since a class is and object type by ref, is there any possibility of the application confusing the object call to the method if the instantiating page is hit at the same time?

If you can give a solid explanation on this, the points are yours!

Thanks in advance.
ASKER CERTIFIED SOLUTION
Avatar of mmarinov
mmarinov

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Martin.  You the man!

Way to dig deep on that explanation and really go the extra theortical mile.

Cheers,