0

私は、潜在的に(ほとんど常に)いくつかのレベルのネストを持つユーザー定義オブジェクトをメンバーごとに比較するためのジェネリックメソッドを作成しようとしています。ここにある例に少しひねりを加えて作業しています。プロパティを等値演算子 (pTypes 配列内のもの) と比較できない場合は、現在のプロパティを渡す再帰呼び出しを行います。私が持っているコードはコンパイルされません。再帰呼び出しでさまざまな構文を試しましたが、正しい構文は何ですか? それとも、これをまったく行うことができますか?

これが今の私の方法です。

    public static string[] MemberWiseCompare<T>(T act, T exp) where T : ICommonObject
    {
        List<string> errors = new List<string>();

        if (act != null && exp != null)
        {
            Type[] pTypes = { typeof(int), typeof(bool), typeof(string), typeof(float), typeof(double), typeof(DateTime) };
            Type type = typeof(T);
            foreach (PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
            {
                if (pTypes.Contains(pi.PropertyType))
                {
                    if (type.GetProperty(pi.Name).GetValue(act, null) != type.GetProperty(pi.Name).GetValue(exp, null))
                    {
                        errors.Add(pi.Name);
                    }
                }
                else
                {
                    string[] innerErrors = MemberWiseCompare<pi.PropertyType>(pi.GetValue(act, null), pi.GetValue(exp, null));
                }
            }
        }
        return null;
    }

もちろん、まだ実装していないメソッドの他の部分 (関数の下部でエラーを集計し、null 以外のものを返す) がありますが、当面は、再帰MemberWiseCompareを機能させることだけに関心があります。そこから、残りを把握できます。ジェネリックに指定した型(つまり pi.PropertyType )からコンパイラが何を取り除いているかを理解するのに問題があると思います。ジェネリック呼び出しで使用する型を提供しているので、これでうまくいくと思いました。また、より具体的なタイプではなくをGetValue返すように、値をボックス化することでいくつかの問題が発生することも予想されます。object

EDIT:コンパイラエラーは、古き良き「最適なオーバーロードされたメソッドには無効な引数があります」です

4

2 に答える 2

1

It does not compile because a generic argument value has to be available at compile time. In the inner call to the MemberWiseCompare you are trying to pass to it a value only available at runtime.

The funny thing is that you do not really need it to be generic - you use reflection to explore the type and you do not need the actual type of the arguments compile time. Just give both act and exp the iCommonObject type and the compilation will go through

于 2013-05-16T21:22:41.613 に答える