Generics
От: dennis.yolkin  
Дата: 29.09.10 14:17
Оценка:
Как реализовать метод f() без использования reflection?

      interface Iface
      {
      }

      class T : Iface
      {
      }

      class C<T> where T : Iface
      {
         public void foo()
         {
            Console.WriteLine("FOO");
         }
      }


      static void f(object obj)
      {
         // если динамический тип obj совместим с C<T>, вызвать у него foo()
      }
Re: Generics
От: nikov США http://www.linkedin.com/in/nikov
Дата: 29.09.10 14:28
Оценка:
Здравствуйте, dennis.yolkin, Вы писали:

DY>Как реализовать метод f() без использования reflection?


Можно примерно так:

static void f(object obj)
{
    bool success = false;
    try
    {
        InvokeFooIfObjIsC((dynamic)obj, out success);
        return;
    }
    catch (RuntimeBinderException)
    {
        if(success)
            throw;
    }

    // obj не является C<T>, делаем что-то другое
}

static void InvokeFooIfObjIsC<T>(C<T> c, out bool success) where T : Iface
{
    success = true;
    c.foo();
}


Хотя тут тоже есть скрытый рефлекшн. Но, с другой стороны, он внутри DLR и хитро оптимизирован с использованием кеширования и т.д.
Re: Generics
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.09.10 03:10
Оценка: +2
Здравствуйте, dennis.yolkin, Вы писали:

DY>Как реализовать метод f() без использования reflection?


DY>
DY>      interface Iface
DY>      {
DY>      }

DY>      class T : Iface
DY>      {
DY>      }

DY>      class C<T> where T : Iface
DY>      {
DY>         public void foo()
DY>         {
DY>            Console.WriteLine("FOO");
DY>         }
DY>      }


DY>      static void f(object obj)
DY>      {
DY>         // если динамический тип obj совместим с C<T>, вызвать у него foo()
DY>      }
DY>

В данном примере сигнатура foo от T не зависит, поэтому я бы сделал так:
public abstract class C
{
   public abstract void foo();
}
public class C<T>:C where T:Iface
{
  public override void foo()
  {
    Console.WriteLine("FOO");
  }
}
public static void f(object obj)
{
  if (obj is C)
  {
    ((C)obj).foo();
  }
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.