0

いくつかのクラスで次のことができるようにしたいと思います。

var obj1 = new MyClass { Id = 1 };
var obj2 = new MyClass { Id = 2 };
obj1.Compare(obj2);

私は次の拡張メソッドを作成しました(ここでの別の質問に触発されました):

public static class ObjExt
{
    public static ICollection<string> Compare<T>(this T obj1, T obj2)
    {
        var properties = typeof(T).GetProperties();
        var changes = new List<string>();

        foreach (var pi in properties)
        {
            var value1 = typeof(T).GetProperty(pi.Name).GetValue(obj1, null);
            var value2 = typeof(T).GetProperty(pi.Name).GetValue(obj2, null);

            if (value1 != value2 && (value1 == null || !value1.Equals(value2)))
            {
                changes.Add(string.Format("Value of {0} changed from <{1}> to <{2}>.", pi.Name, value1, value2));
            }
        }
        return changes;
    }

これは、比較したいすべてのクラスでメソッドを作成すると機能するので、スーパークラスを DRY に移動することにしました。

public class MyClass
{
    public int Id { get; set; }

    public ICollection<string> CompareMe<T>(T obj2)
    {
        return Compare<T>(obj2);
    }
}

これをスーパー クラスに移動すると、次のコンパイル エラーが発生します。

インスタンス型引数 'SuperClass' を 'T' に変換できません

スーパークラスでこれを行うと:

return this.Compare<T>(obj2);

次のようなコンパイル エラーが表示されます。

メソッド 'Compare(T, T)' の型引数は、使用法から推測できません。型引数を明示的に指定してみてください。

スーパークラスでこれをジェネリックにする方法は?

4

3 に答える 3

1

この拡張方法:

public static bool GenericTest<T>(this T obj1, T obj2)
{
}

コンパイラは実際に何が何であるかについての手がかりがないため、コンパイルされませんT。型を推測するコンテキストがありません。のようなものを使用するかwhere T: SuperClass、メソッドのパラメーターを に変更する必要がありますthis SuperClass obj1, SuperClass obj2

于 2012-12-03T16:14:03.557 に答える
1

SuperTestメソッドに一般的な制約を追加できます。

public bool SuperTest<T>(T obj2) where T: SuperClass
            {
                return this.GenericTest(obj2);
            }

Tそして、拡張メソッドを次のように置き換えSuperClassます。

public static bool GenericTest(this SuperClass obj1, SuperClass obj2)
        {
            return true;
        }

これがあなたが考えていたものかどうかはわかりませんが。

于 2012-12-03T16:14:11.260 に答える
1

スーパークラスがどのように見えるかわかりません。しかし、これはうまくコンパイルされます:

public class SuperClass
{
    public bool GenericTest<T>(T obj2)
    {
       return ObjExt.GenericTest(obj2, obj2);
    }
}

public class MyClass : SuperClass
{
    public int Id { get; set; }

    public bool SuperTest<T>(T obj2)
    {
        return this.GenericTest<T>(obj2);
    }
}

public static class ObjExt
{
    public static bool GenericTest<T>(this T obj1, T obj2)
    {
        return true;
    }
}
于 2012-12-03T16:05:50.090 に答える