Reputation: 882
I would like to be able to do the following for several classes:
var obj1 = new MyClass { Id = 1 };
var obj2 = new MyClass { Id = 2 };
obj1.Compare(obj2);
I made the following extension method (inspired by a different question inhere):
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;
}
Now, this works if I make a method in all classes I want to compare, so I figured I'd move it so a super class to DRY.
public class MyClass
{
public int Id { get; set; }
public ICollection<string> CompareMe<T>(T obj2)
{
return Compare<T>(obj2);
}
}
If I move it to a super class, I get this compile error:
Cannot convert instance type argument 'SuperClass' to 'T'
If I do this in my super class:
return this.Compare<T>(obj2);
I get a compile error saying:
The type arguments for method 'Compare(T, T)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
How to make this generic in a super class?
Upvotes: 0
Views: 184
Reputation: 46997
Not sure how your super class looks. But this compiles fine:
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;
}
}
Upvotes: 1
Reputation: 4172
You can add a generic constraint on the SuperTest
method:
public bool SuperTest<T>(T obj2) where T: SuperClass
{
return this.GenericTest(obj2);
}
And replace T
in the extensionmethod with SuperClass
:
public static bool GenericTest(this SuperClass obj1, SuperClass obj2)
{
return true;
}
I'm not sure if this is what you had in mind though.
Upvotes: 1
Reputation: 2125
This extension method:
public static bool GenericTest<T>(this T obj1, T obj2)
{
}
will not compile, because the compiler has no clue about what T
really is: there is no context to infer types from. You either need to use something like where T: SuperClass
or change the method parameters to this SuperClass obj1, SuperClass obj2
.
Upvotes: 1