В моем понимании, ваша конечная цель будет void collection1.CollectionRefresh(collection2)
, где collection1.GetType()==collection2.GetType()==typeof(ObservableCollection<TestClassC>)
Полагаю, вы хотите позвонить
TestClassA testA = new TestClassA();
List<TestClassB> list = new List<TestClassB>();
testA.CollectionA.CollectionRefresh(list);
Тогда T
будет TestClassB
, а ObservableCollection<TestClassC> CollectionB
будет вашим целевым свойством.
property.GetValue(TestClassB someB)
будет возвращать объект, который не может вызывать void CollectionRefresh(collection2)
, поэтому вы застряли, я прав??
Это вложенная общая проблема.Если бы вы также указали TestClassC
как T2
, тогда это было бы так просто.
Обычно у нас был бы неуниверсальный базовый класс, чтобы мы могли явно привести его к этому.К сожалению, ObservableCollection<T>
не наследуется от функционального ObservableCollection
класса.
Вот мое предложение.Вы должны использовать как дерево выражений, так и отражение, чтобы получить метод CollectionRefresh
и затем вызвать его, но это может быть излишним.
В любом случае, попробуйте это.
public static void CollectionRefresh<T>(this ObservableCollection<T> collection, List<T> items)
{
//Method Content
PropertyInfo[] properties = typeof(T).GetProperties();
foreach(PropertyInfo property in properties)
{
if (property.PropertyType.IsGenericType && typeof(ObservableCollection<>).IsAssignableFrom(property.PropertyType.GetGenericTypeDefinition()))
{
MethodInfo refreshMethod = property.PropertyType.GetMethod("CollectionRefresh");
var instanceT1 = Expression.Parameter(typeof(T), "otherT1");
var instanceT2 = Expression.Parameter(typeof(T), "otherT2");
var prop1 = Expression.Call(instanceT1, property.GetMethod);
var prop2 = Expression.Call(instanceT2, property.GetMethod);
var collection1 = Expression.Convert(prop1, property.PropertyType);
var collection2 = Expression.Convert(prop2, property.PropertyType);
var refresh = Expression.Call(collection1, refreshMethod, collection2);
var lambda = Expression.Lambda<Action<T, T>>(refresh, instanceT1, instanceT2);
Action<T, T> func = lambda.Compile();
func(oldCollection, newList);
}
}
//Method Content
}