Comments 19
так и не понял на кой такой изврат?
давайте еще поплачем про ковариантность — хотя в 4 некая имитация будет.
давайте еще поплачем про ковариантность — хотя в 4 некая имитация будет.
0
Так ли уж часто нужно возвращать объект того же самого типа из экземплярного метода? Ну т.е., кроме как Clone(), не могу придумать никакого общего применения этой штуке.
0
Ну вот хотя бы и Clone(). Разве одного метода мало? :)
Удобно так писать и тот же Compare, который есть в примере кода. Конечно, можно записать в параметрах базовый тип и приводить к текущему типу, но ведь приятнее, когда все на этапе компиляции сделается.
Пример из нашего кода. С клиента приходят два объекта (десериализуется) — состояние до и после редактирования. Нужно сравнить их и сделать апдейт. Чтобы сравнить, делаем в дженерике метод bool Equals( TThis other ). Базовый метод сравнивает ощие для всех таких объектов свойства, а унаследованный добавляет к этому сравнение доп свойств.
Удобно так писать и тот же Compare, который есть в примере кода. Конечно, можно записать в параметрах базовый тип и приводить к текущему типу, но ведь приятнее, когда все на этапе компиляции сделается.
Пример из нашего кода. С клиента приходят два объекта (десериализуется) — состояние до и после редактирования. Нужно сравнить их и сделать апдейт. Чтобы сравнить, делаем в дженерике метод bool Equals( TThis other ). Базовый метод сравнивает ощие для всех таких объектов свойства, а унаследованный добавляет к этому сравнение доп свойств.
+1
Ну реализуйте в наследованном классе явный IComparable, а при необходимости обращайтесь к базовой реализации. Да, чуть больше кода, но зато без всяких хитростей.
0
можно, например, вот так:
Copy Source | Copy HTML
- public TEntity Load(DataContext context, object pk)
- {
- var table = context.GetTable<TEntity>();
- return table.Where(this.FilterByPk(pk)).SingleOrDefault();
- }
-
-
- protected Expression<Func<TEntity, bool>> FilterByPk(object pk)
- {
- var entity = Expression.Parameter(typeof(TEntity), "ent");
- var keyValue = Expression.Property(entity, primaryKey);
- var primaryKeyValue = Expression.Constant(pk, keyValue.Type);
- var body = Expression.Equal(keyValue, primaryKeyValue);
- var expression = Expression.Lambda<Func<TEntity, bool>>(body, entity);
- return expression;
- }
- public void Do()
- {
- var doc = this.Load(dataContext, documentId);
-
- if (doc == null)
- {
- doc = new TEntity()
- {
- CreationTime = DateTime.Now,
- id = documentId,
- };
- dataContext.GetTable<TEntity>().InsertOnSubmit(doc);
- }
- }
-
-
0
Вот еще, узел дерева:
А удобнее было бы для юзания:
public class Node<T> { public List<Node<T>> Children; ... }
А удобнее было бы для юзания:
public class Node<T> { public List<TThis> Children; ... }
+1
У Мейера об этом тоже есть. У него много потрачено на объяснение полезности такой штуки. В Эйфель есть конструкции like anchor или like Current.
У него не только возврат значения. Например в классе есть несколько полей, по идее они должны быть во всех наследниках одного типа, заранее неизвестно какого, это определяется только в конкретной реализации наследника.
У него не только возврат значения. Например в классе есть несколько полей, по идее они должны быть во всех наследниках одного типа, заранее неизвестно какого, это определяется только в конкретной реализации наследника.
+1
Прогресс на лицо, чувствую лет через пять можно будет переключаться с Nemerle на любой mainstream язык без такого уныния, которое испытываю сейчас=)
+1
а я думал, чот я один такой извращенец)))
Copy Source | Copy HTML
- public partial class Budget : BaseDoc<Budget>
- {}
- public abstract class BaseDoc<TEntity> : IDocument where TEntity : BaseDoc<TEntity>, new()
- {}
+1
Предлагаю в таких случаях вместо TEntity писать TThis.
+1
Какая разница, что писать?
TThis — это вообще что-то невразумительное. Как вы себе представляете функцию, которая возвращает значение или принимает аргумент типа, которого еще не существует.
Вот так правильно:
Выбирайте первый или второй вариант, в зависимости от того, лень вам делать приведение типов или нет.
TThis — это вообще что-то невразумительное. Как вы себе представляете функцию, которая возвращает значение или принимает аргумент типа, которого еще не существует.
Вот так правильно:
Copy Source | Copy HTML
- public class Adapter<T>
- {
- public virtual Adapter<T> DoSomething()
- {
- ...
- }
- public virtual U DoSomething<U>() where U: Adapter<T>, new()
- {
- ...
- }
- }
Выбирайте первый или второй вариант, в зависимости от того, лень вам делать приведение типов или нет.
0
Это как раз неправильно. Я не хочу в DoSomething писать ничего. У Вас получается либо:
MyAdapter a = (MyAdapter)obj.DoSomething();
либо
MyAdapter a = obj.DoSomething();
Первй вариант просто неудобный, а второй и вовсе некорректный — тут вместо MyAdapter можно запихать и YourAdapter. Откомпилируется, но не заработает.
Вообще, вся эта система дженериков и служит для того, чтобы писать функции, которые оперируют еще не существующими типами. Мой пример сверху, с TThis вполне рабочий — он компилируется. Пример XuMiX корректен? Вполне. Я только считаю, что если вместо TEntity написать TThis, то будет понятнее.
MyAdapter a = (MyAdapter)obj.DoSomething();
либо
MyAdapter a = obj.DoSomething();
Первй вариант просто неудобный, а второй и вовсе некорректный — тут вместо MyAdapter можно запихать и YourAdapter. Откомпилируется, но не заработает.
Вообще, вся эта система дженериков и служит для того, чтобы писать функции, которые оперируют еще не существующими типами. Мой пример сверху, с TThis вполне рабочий — он компилируется. Пример XuMiX корректен? Вполне. Я только считаю, что если вместо TEntity написать TThis, то будет понятнее.
+1
Сдается мне что можно поменять одно неудобство на другое и написать extension method который будет выдавать тот тип что нужен. Что-нибудь вроде:
public static T DoSomething<T>(this T obj)
{
⋮
}
А может и нельзя ;) так или иначе, согласен – косячненько.0
Sign up to leave a comment.
В дженериках C# мог бы быть полезен “this type”