I am still a beginner developer – so forgive me if I get this question horibly wrong, but I have a class that builds a string based on the properties of another public struct. This used to work fine when the struct was named, but I wanted to allow this class to do the same with any kind of struct so I changed to using objects. This is the methoed I use to loop through the properties and construct the string – this is in a public class called constructors which I then call (without creating an instance of constructors) from the rest of my code.
public string MyConstructor(object TheObject)
{
string S = "";
Type t = TheObject.GetType();
PropertyInfo[] PI = t.GetProperties();
Constructors Cons = new Constructors();
foreach (PropertyInfo info in PI)
{
S = MyConstructor(S, info, info.GetValue(TheObject, null););
}
return S;
}
My problem is that it does not want to get out of the foreach loop. When I replaced it with
for (int i = 0; i < PI.Count(); i++)
{
S = MyConstructor(S, PI[i], PI[i].GetValue(TheObject, null));
}
and ran it through the debugger -> after each loop i goes 0, 1, 0, 1, 0, 1… MyConstructor has 2 overloads… the one above and another with (string, PropertyInfo, object). But even if I change the name of the second method to MyPropertyConstructor the same happens. At the moment the code is called from a form with no Threads so there isn’t any other threads that could in my mind interfere. Also for loop 0 and 1 the method returns empty strings “”. So how do I get out of this loop?
Here is the the rest of the code
public static string MyConstructor(string CompiledString, PropertyInfo PropertyToAdd, object ThisValue)
{
string s = "";
//object ThisValue = PropertyToAdd.GetValue(PropertyToAdd, null);
//See if there is something to work with
if(PropertyToAdd != null)
{
//Remove items which has been set not to record
if (PropertyToAdd.GetCustomAttributes(typeof(DontRecord), true).Length > 0)
{
if(((DontRecord)PropertyToAdd.GetCustomAttributes(typeof(DontRecord), true)[0]).Record)
{
return CompiledString;
}
}
//see if it is the first time using the compile string
if (CompiledString != "")
{
s += ";";
}
//For Testing
int testint = 0;
//only record items that where default value is different to their value
Object[] Attr = PropertyToAdd.GetCustomAttributes(typeof(DefaultValueAttribute), true);
//see if there is a default value set
if (Attr.Length > 0)
{
//Get Constructorname value
Object[] constructorname = PropertyToAdd.GetCustomAttributes(typeof(ConstructorName), true);
if (constructorname.Length > 0)
{
s += ((ConstructorName)constructorname[0]).Name.ToString() + "=";
//If value is a string
if (PropertyToAdd.PropertyType == typeof(string))
{
if (Convert.ToString(((DefaultValueAttribute)Attr[0]).Value) != (string)ThisValue) { s += ThisValue; } else { s = ""; }
}
//Incase value is an int
else if (PropertyToAdd.PropertyType == typeof(int) && int.TryParse(ThisValue.ToString(), out testint))
{
if (Convert.ToInt32(((DefaultValueAttribute)Attr[0]).Value) != (int)ThisValue) { s += Convert.ToString((int)ThisValue); } else { s = ""; }
}
//Incase value is a bool
else if (PropertyToAdd.PropertyType == typeof(bool))
{
if (Convert.ToBoolean(((DefaultValueAttribute)Attr[0]).Value) != (bool)ThisValue)
{
if ((bool)ThisValue) { s += "True"; } else { s += "False"; }
}
else { s = ""; }
}
else
{
s = "";
}
}
else
{
//There is no ConstructorName so therefore cannot create
return CompiledString;
}
}
else
{
return CompiledString;
}
}
return CompiledString += s;
}
}
Here is a part of the type of objects passed initially to MyConstructor the public struct example
public struct ODBCDataString
{
#region Variables
#region General Variables
static string _connection = “”;
static string _saveString = “”;
static string _unsaveString = “”;
#endregion General Variables
#region Security Variables
static string _userID = "";
static string _password = "";
#endregion Security Variables
#region Source Variables
static string _dsn = "";
static string _driver = "";
#endregion Source Variables
#endregion Variables
#region Properties
#region General
[Browsable(false)]
public string ConnectionString { get { return _connection; } set { _connection = value; } }
[Browsable(false)]
public string SaveString
{
get
{
Constructors Cons = new Constructors();
string MyS = Cons.MyConstructor((object)this);
return MyS;
}
}
[Browsable(false)]
public string UnsaveString
{
get
{
Constructors Cons = new Constructors();
string MyS = Cons.MyConstructor((object)this);
//string MyS = Constructors.MyConstructor((object)this);
if (_password != "")
{
MyS += ";Password=" + _password;
}
return MyS;
}
}
#endregion General
#region Source
[DisplayName("DSN")]
[Description("The DSN to use when connecting to the Data Source")]
[DefaultValue("")]
[Category("Source")]
[ConstructorName("Dsn")]
public string DSN { get { return _dsn; } set { _dsn = value; } }
… This is basically just a brief overview of the type of structs / objects that is passed
Ok sorry for wasting time here, but I found the problem. It is as HOBO suggested. one of my properties also called the same method (actually it was the second property of the exact class I set as the example above. I commented that one out and code was working. After an entire day spent – I feel like an idiot and wasted all you guys’ time… THANK You SO SO Much for all your help 🙂 I almost gave up on developing all together 🙂