Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Обобщения


Автор: mullih 18.8.2008, 23:33
Доброго времени суток.

известен тип, при компиляции не известны. 

Код

Type type = obj.GeType();


Необходимо создать Список и указатель. Примерно такого вид

Код

class c
 {
  private void CreateList(object obj)
  {
    IList<type> list = new List<type>();
    list.add((type)obj);
    if (ListEvent!=null)
      ListEvent(list);
  }

  public event ListHandler<type> ListEvent;
}

public delegate ListHandler<T>(IList<T> list);



Собственно вопрос что засунуть на место "type" во втором коде или как это по другому описать. Заранее "type" не известен. Класс из "class" c в "class c<T>" не хочу делать так как это контрол и в дизайнер после этого будет ругаться.  Obj создается с помощью отражения поэтому object просто обертка. На место "type" object не могу поставить т.к. от того что прийдет подписчику в <T> от события зависит дальнейшее поведение

Заранее благодарен за помощь

Автор: mihryak 19.8.2008, 09:20
Цитата(mullih @  19.8.2008,  00:33 Найти цитируемый пост)
Код

IList<type> list = new List<type>();

afaik, эта строчка в момент компиляции преобразуется в код, работающий с конкретным типом, т.е. дженерики - compile-time, а не run-time

посмотри http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.makegenericmethod.aspx

Автор: QryStaL 19.8.2008, 09:50
Цитата(mihryak @  19.8.2008,  09:20 Найти цитируемый пост)
дженерики - compile-time, а не run-time

наоборот

Автор: mihryak 19.8.2008, 11:34
QryStaL,
мм.... я вообще-то имел в виду то, что тип дженерика вбилдивается в код при компиляции
если пойти дальше, то под run-time я имел в виду уже прошедший через JIT код (некорректное использование термина, согласен) - где-то (если не ошибаюсь - RSDN) читал, что, например, List<int> после JIT'а представлен как простой массив целых чисел

а вообще тема весьма интересная
вот, http://research.microsoft.com/projects/clrgen/generics.pdf нашёл

Автор: QryStaL 19.8.2008, 11:42
Цитата(mihryak @  19.8.2008,  11:34 Найти цитируемый пост)
тип дженерика вбилдивается в код при компиляции

при JIT-компиляции, а это уже все-таки рантайм...

Автор: mihryak 19.8.2008, 11:48
Цитата(QryStaL @  19.8.2008,  12:42 Найти цитируемый пост)
при JIT-компиляции, а это уже все-таки рантайм... 

открой рефлектором код с джерериками - все типы будут проставлены
Код

L_0001: newobj instance void test.Program/Generic<int32>::.ctor(!0)

Автор: mullih 19.8.2008, 14:57
Спасибо за помощь и вдогонку еще вопросик по этой же теме

Код

    public class C1
    {
        public virtual int Id { get; set; }
    }

    public abstract class Test<D> where D : C1
    {
        A a = new A();
        public void GetById()
        {
            var result = a.GetById<D>(D.Id); //
        }
    }



D.Id как правильно записать чтоб для любого объекта <D> типа наследуемого от С1 можно было использовать свойство Id?

ЗЫ есть подозрение что такого быть вообще не может без самого объекта но вдруг всетаки можно)

Автор: nagg 19.8.2008, 18:22
Ты б хоть строчку  where D : C1 - в комменты вознёс, а то я чуть глаза не поломал.
var result = a.GetById<D>(D.Id);
ты у типа пытаешься вызвать экземплярное свойство не создавая объект.

Автор: mullih 19.8.2008, 19:30
>var result = a.GetById<D>(D.Id);
>ты у типа пытаешься вызвать экземплярное свойство не создавая объект.

я об этом тоже подумал но потом )


>Ты б хоть строчку  where D : C1 - в комменты вознёс, а то я чуть глаза не поломал.

в вот как раз с это строчкой все в порядке 
Это ограничение. <D> может быть только типом С1 или его наследниками

Автор: source777 19.8.2008, 20:49
Цитата(mihryak @  19.8.2008,  11:48 Найти цитируемый пост)
открой рефлектором код с джерериками - все типы будут проставлены


mihryak, ты не понимаешь, что значит "в момент компиляции преобразуется в код, работающий с конкретным типом", обратись для разъяснения этого вопроса к шаблонам(templates) С++, вот там compile-time и для каждого параметра шаблона действительно компилятор создаст свой тип, в C# и List<int>, и List<string>, и List<char> - это один класс, в С++ в аналогичном случае будет _три_ разных класса.

Автор: mihryak 19.8.2008, 21:15
source777, я выше пояснил
что класс один - не спорю, так и есть, и моя цитата из рефлектора тоже об этом говорит
написал её, чтобы показать, что не существует в IL'е такой штуки, как List<instanceOfSomeType.GetType()>, конкретный тип должен быть явно задан в коде

Автор: mullih 22.8.2008, 19:16
Вроде нашел решение моего топика

http://www.codeproject.com/KB/dotnet/InvokeGenericMethods.aspx

Возможно не панацея от всех недуг но может быть комунибудь пригодится

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)