#c# #generics #expression
#c# #общие #выражение
Вопрос:
У меня есть следующий метод, который возвращает универсальный объект типа INamedProperty<TReturn>
на основе возвращаемого типа определенного выражения. Мне нужно сохранить ссылку на объект, который возвращается этим методом для будущей обработки. В каком типе я должен его сохранить? Object
Было бы нормально? Как я мог бы привести его к соответствующему INamedProperty<TReturn>
позже? Нужно ли мне также сохранять тип TReturn
?
public class PropertyBuilder<T> : IPropertyBuilder<T> where T : class {
public INamedProperty<TReturn> Named<TReturn>(Expression<Func<T, TReturn>> property) {
o = new NamedProperty<TReturn>();
// how do I store o as an instance of the encapsulating class?
}
}
Заранее спасибо!
Комментарии:
1. Я предполагаю,
T
является аргументом типа для заключающего класса?2. Да. Извиняюсь, что не уточнил это. Я приведу еще немного контекста в своем вопросе.
3. Как вы будете использовать этот объект в будущей обработке? Если ссылки на объект достаточно, просто используйте это. Что произойдет, если именованный универсальный метод вызывается сначала как Named<A> , затем как Named<B>?
Ответ №1:
Я бы попытался реализовать универсальный, неуниверсальный INamedProperty
, который мог бы реализовать необходимые вам операции:
interface INamedProperty
{
// Informational
Type ContainingType { get; }
string Name { get; }
Type ReturnType { get; }
// Operations (for example)
void CopyTo(object obj, INamedProperty property);
}
Затем реализуйте их в универсальном NamedProperty:
class NamedProperty<T> : INamedProperty { ... }
Комментарии:
1. Это то, к чему я в итоге пришел. Спасибо за ввод!
Ответ №2:
Почему бы не использовать дополнительный параметр действия вместо сохранения ссылки? Вы сталкиваетесь с проблемой, потому что TReturn на самом деле не существует в конкретной форме вне контекста выполнения вашего метода; подумайте о более функциональном программировании и менее процедурном.
редактировать: добавлен пример кода
public INamedProperty<TReturn> Named<TReturn>(Expression<Func<T, TReturn>> property, Action<INamedProperty<TReturn>> action)
{
var o = new NamedProperty<TReturn>();
action.Invoke(o);
return o;
}
Комментарии:
1. Не могли бы вы подробнее остановиться на этом, пожалуйста?
2. Вы знаете, что C # позволяет вам просто вызывать делегатов, вам не нужно использовать
Invoke()
? например:action(o);
,ret = func(a);
.