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、オブジェクト)のオーバーロード。しかし、2 番目のメソッドの名前を 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 の例

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さんのおっしゃる通りです。私のプロパティの 1 つも同じメソッドを呼び出していました (実際には、上記の例で設定した正確なクラスの 2 番目のプロパティでした。その 1 つをコメントアウトすると、コードが機能していました。丸 1 日過ごした後、私はばかで無駄になったように感じます皆さんのすべての時間...ありがとうございました。すべての助けに感謝します:)私はほとんど一緒に開発することをあきらめました:)

于 2012-09-20T15:09:35.180 に答える