2

我仍然是一名初学者开发人员 - 如果我把这个问题弄错了,请原谅我,但我有一个类可以根据另一个公共结构的属性构建一个字符串。当结构被命名时,这曾经可以正常工作,但我想让这个类对任何类型的结构做同样的事情,所以我改为使用对象。这是我用来遍历属性并构造字符串的方法——这是在一个名为构造函数的公共类中,然后我从我的其余代码中调用(不创建构造函数的实例)。

    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;
    }

我的问题是它不想退出 foreach 循环。当我用

        for (int i = 0; i < PI.Count(); i++)
        {
            S = MyConstructor(S, PI[i], PI[i].GetValue(TheObject, null));
        }

并通过调试器运行它->在每个循环之后我进入 0、1、0、1、0、1... MyConstructor 有 2 个重载...上面的一个和另一个带有(字符串、PropertyInfo、对象)的重载。但即使我将第二种方法的名称更改为 MyPropertyConstructor 也会发生同样的情况。目前,代码是从没有线程的表单中调用的,因此在我看来没有任何其他线程可以干扰。同样对于循环 0 和 1,该方法返回空字符串“”。那么我该如何摆脱这个循环呢?

这是其余的代码

    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;
    }

}

这是最初传递给 MyConstructor 的部分对象类型的公共结构示例

public struct ODBCDataString { #region 变量 #region 通用变量 static string _connection = ""; 静态字符串 _saveString = ""; 静态字符串 _unsaveString = ""; #endregion 通用变量

        #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; } }

...这基本上只是对传递的结构/对象类型的简要概述

4

2 回答 2

0
namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        Test1 t1 = new Test1();
        string result = ObjToString<Test1>(t1);
        Console.WriteLine(result);
        Console.ReadKey();
    }

    public static string ObjToString<T>(T obj)
    {
        if (obj == null)
        {
            throw new Exception("passed in parameter is null");
        }

        StringBuilder sb = new StringBuilder();

        Type t = obj.GetType();
        PropertyInfo[] properties = t.GetProperties();

        foreach (var property in properties)
        {
            sb.Append(property.Name);
            sb.Append(",");
        }

        return sb.ToString();
    }
}

public struct Test1
{
    public string Property1 { get; set; }
    public string Property2 { get; set; }
}
}
于 2012-09-20T13:28:31.353 回答
0

好的抱歉在这里浪费时间,但我发现了问题。正如HOBO建议的那样。我的一个属性也调用了相同的方法(实际上它是我在上面的示例中设置的确切类的第二个属性。我评论说一个输出并且代码正在工作。花了一整天之后 - 我觉得自己像个白痴并且浪费了你们所有的时间......非常感谢你们的帮助:)我几乎放弃了一起开发:)

于 2012-09-20T15:09:35.180 回答