Re[5]: C# ликбез
От: Ursus Россия  
Дата: 16.10.02 14:23
Оценка:
Здравствуйте DarkGray, Вы писали:

U>>Убедительно Полностью согласен Но опять же это просто облегчение. Та же проблема в COM.


DG>Если Com реализовался на языке C++, то проблем не было.


Были еще какие.
IInterface1 и его реализация — в одной Dll, написанной на С++.
IInterface2 и его реализация — в другой DLL, написанной на С++.
Как наследование реализации строить для IInterace3, который должен наследоваться от обоих?
Да пребудет с тобой Великий Джа
Re[6]: C# ликбез
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 16.10.02 14:27
Оценка:
U>Были еще какие.
U>IInterface1 и его реализация — в одной Dll, написанной на С++.
U>IInterface2 и его реализация — в другой DLL, написанной на С++.
U>Как наследование реализации строить для IInterace3, который должен наследоваться от обоих?

Если именно наследоваться, то никак...

А если без наследования, то можно было через агрегацию подцепить.
Re[7]: C# ликбез
От: Ursus Россия  
Дата: 16.10.02 14:36
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>А если без наследования, то можно было через агрегацию подцепить.


Убедил, Множественое наследование помогло бы в некоторых ситуациях Правда могло и внести изрядно путаницы. А в случае множетства наследуемых интерфейсов... в конце концов можно с скопировать реализацию Если исходныйкод доступен Но прописывать похожие свойства действительно бесит.
Да пребудет с тобой Великий Джа
Re[3]: C# ликбез
От: Andy77 Ниоткуда  
Дата: 16.10.02 14:57
Оценка:
Здравствуйте DarkGray, Вы писали:

DG>И как эту задачу решить без множественного наследования?


Меня удивляет, что нигде в современных языках не встречается такая конструкция (ведь наследование реализации можно представить комбинацией аггрегации и делегирования) —

public interface IActive
{
  public bool IsActive
  {
    get;
    set;
  }
}

public class ActiveImpl : IActive
{
  bool _isActive;
  public bool IsActive
  {
    get {return _isActive;}
    set {_isActive = value;}
  }

}

public interface INaming
{
  public string Name
  {
    get;
    set;
  }
}

public class NamingImpl : INaming
{
  string _name;
  public string Name
  {
    get {return _name;}
    set {_name = value;}
  }
}

public class GenericClass : IActive, INaming
{
  // all IActive calls are delegated to this object
  private implements IActive active = new ActiveImpl();  

  // all INaming calls are delegated to this instance
  private implements INaming naming = new ActiveImpl();
}


вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.
Re[4]: C# ликбез
От: Igor Trofimov  
Дата: 16.10.02 15:11
Оценка:
A>Меня удивляет, что нигде в современных языках не встречается такая конструкция
A>вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.

Нечто очень близкое есть в Delphi'йском ObjectPascal. Только там надо для каждого метода реализуемого интерфейса указать какой объект и какой его метод подставлять.
Re: C# ликбез
От: Atilla Россия  
Дата: 16.10.02 15:34
Оценка:
Здравствуйте neutrino, Вы писали:

N>я знаком с шарпом крайне поверхностно, но, если не ошибаюсь, он не поддерживает множественное наследование.

N>к каким проблемам (и возможно преимуществам) это приводит и какие в нем есть альтернативные подходы.

А еще в C# нет шаблонов. Это тоже дает некоторые преимущества (программисту не нужно осваивать эту довольно непростую весчь), но и ряд недостатков. То же самое касается и множественного наследования реализации и управления памятью. MS решили, что программеры a-priori недостаточно внимательны и обучаемы (в каком-то смысле это верно) и решили все как можно сильнее упростить.
Но для особо продвинутых оставили лазейку: Managed C++.
Кр-ть — с.т.
Re[2]: C# ликбез
От: IT Россия linq2db.com
Дата: 16.10.02 15:53
Оценка:
Здравствуйте Ursus, Вы писали:

U>Честно говоря я пока не встречал реальных задач где бы требовалось множественное наследование классов.


ATL — великолепный пример использования множественного наследования в купе с шаблонами. Им можно отметать любые инсинуации против необходимости наличия множественного наследования (пусть будет наследования реализации, если хотите) и шаблонов в современных языках программирования.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: C# ликбез
От: Ursus Россия  
Дата: 16.10.02 16:04
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте Ursus, Вы писали:


U>>Честно говоря я пока не встречал реальных задач где бы требовалось множественное наследование классов.


IT>ATL — великолепный пример использования множественного наследования в купе с шаблонами. Им можно отметать любые инсинуации против необходимости наличия множественного наследования (пусть будет наследования реализации, если хотите) и шаблонов в современных языках программирования.


Прекрасный пример Умыли Хоть может и можно было бы поспорить наверное, но согласен.


Немного уйду в сторону, просто интересно, попадались ли кому задачи аналогичные решаемым ATL?
Да пребудет с тобой Великий Джа
Re[4]: C# ликбез
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.10.02 18:06
Оценка: 6 (1)
Здравствуйте Andy77, Вы писали:

A>Меня удивляет, что нигде в современных языках не встречается такая конструкция (ведь наследование реализации можно представить комбинацией аггрегации и делегирования) —



A>вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.


Вот пример подобного на шарпе

namespace ConnectingImpl {

 public interface Int1 {
  string MethodA(string par1);
 }

 public class Impl1 : Int1 {
  public string MethodA(string par1) {
   return "Implementation 1 "+par1;
  }
 }

 public interface Int2 {
  string MethodB();
  void MethodC();
 }

 public class Impl2 : Int2 {
  public string MethodB() {
   return "Implementation 2";
  }
  public void MethodC() {
   System.Console.WriteLine("MethodC");
  }
 }

 public class Test {

  [Implements(typeof(Int1))]
  public Impl1 impl1 = new Impl1();

  [Implements(typeof(Int2))]
  public Impl2 impl2 = new Impl2();

  static void Main() {
   ImplBuilder ib = new ImplBuilder(typeof(Test));

   object conimpl = ib.CreateInstance(new Test());

   System.Console.WriteLine(((Int1) conimpl).MethodA("X"));
   System.Console.WriteLine(((Int2) conimpl).MethodB());
   ((Int2) conimpl).MethodC();
  }

 }

}
... << RSDN@Home 1.0 alpha 12 (developers build)>>
AVK Blog
Re[4]: C# ликбез
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.10.02 19:46
Оценка:
Здравствуйте Ursus, Вы писали:

U>Немного уйду в сторону, просто интересно, попадались ли кому задачи аналогичные решаемым ATL?


ATL — это стиль решения задач. Теже задачи решаются и другими способами. В том же Дельфи множественного наследования нет, а КОМ реализован.
... << RSDN@Home 1.0 alpha VladD2.1.0.alpha 12.1.0.1019.39707 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: C# ликбез
От: IT Россия linq2db.com
Дата: 16.10.02 19:53
Оценка:
Здравствуйте VladD2, Вы писали:

VD>ATL — это стиль решения задач. Теже задачи решаются и другими способами. В том же Дельфи множественного наследования нет, а КОМ реализован.


Но с ATL'ем то приятнее работать, не так ли?
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: C# ликбез
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.10.02 20:12
Оценка:
Здравствуйте IT, Вы писали:

VD>>ATL — это стиль решения задач. Теже задачи решаются и другими способами. В том же Дельфи множественного наследования нет, а КОМ реализован.


IT>Но с ATL'ем то приятнее работать, не так ли?


Тебя не поймешь. То с Шарпом приятнее, то с АТЛ-ом. Ты давай ориентацию выбирай.

PS

Если серьезно, то АТЛ использует наследование в основном для подключения реализации. Тут можно было бы обойтись и более простыми мерами. Ведь за множественное наследование приходится платить половиной недостатков С++-а. Думаю, лучшим решением было бы добавить возможноть присоеденения реализации без множественного наследования. Синтаксис мы тут уже обсуждали.

PSS

За одно нужно добавить шаблоны, const для параметров и локальных переменных... Куда? Думаю ты понял.
... << RSDN@Home 1.0 alpha VladD2.1.0.alpha 12.1.0.1019.39707 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: C# ликбез
От: Andy77 Ниоткуда  
Дата: 16.10.02 20:28
Оценка:
Здравствуйте AndrewVK, Вы писали:

AVK>Здравствуйте Andy77, Вы писали:


A>>Меня удивляет, что нигде в современных языках не встречается такая конструкция (ведь наследование реализации можно представить комбинацией аггрегации и делегирования) —


AVK>

A>>вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.

AVK>Вот пример подобного на шарпе


Хм... оценку я тебе уже поставил, а пример не компилируется признавайся, откуда нужно брать этот таинственный Implements ?
Re[7]: C# ликбез
От: IT Россия linq2db.com
Дата: 16.10.02 20:33
Оценка:
Здравствуйте VladD2, Вы писали:

VD>Тебя не поймешь. То с Шарпом приятнее, то с АТЛ-ом. Ты давай ориентацию выбирай.


Да я уже выбрал, причём в отличии от Мишки.ex.NET я таки убедил народ в правильности моего выбора

VD>Если серьезно, то АТЛ использует наследование в основном для подключения реализации. Тут можно было бы обойтись и более простыми мерами. Ведь за множественное наследование приходится платить половиной недостатков С++-а. Думаю, лучшим решением было бы добавить возможноть присоеденения реализации без множественного наследования. Синтаксис мы тут уже обсуждали.


Я в своей реплике как раз про это и намекал, зная что обязательно будут инсинуации

VD>За одно нужно добавить шаблоны, const для параметров и локальных переменных... Куда? Думаю ты понял.


Кстати, в MC++ кое что уже из этого есть (я про использование реализации). В нём, если класс или его предки имеет метод с таким же названием и сигнатурой, то он по умалчанию используется для имплементации метода интерфейса.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: C# ликбез
От: VladD2 Российская Империя www.nemerle.org
Дата: 16.10.02 20:42
Оценка:
Здравствуйте Andy77, Вы писали:

A>Хм... оценку я тебе уже поставил, а пример не компилируется признавайся, откуда нужно брать этот таинственный Implements ?


Сделай поиск по сайту...
... << RSDN@Home 1.0 alpha VladD2.1.0.alpha 12.1.0.1019.39707 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: C# ликбез
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 16.10.02 21:06
Оценка:
Здравствуйте Andy77, Вы писали:

A>Хм... оценку я тебе уже поставил, а пример не компилируется признавайся, откуда нужно брать этот таинственный Implements ?


using System;
using System.Reflection;
using System.Collections;
using System.Text;
using System.CodeDom.Compiler;

namespace ConnectingImpl {

 [AttributeUsage(AttributeTargets.Field)]
 public class ImplementsAttribute : Attribute {

  private Type intf;
  public Type Interface {
   get {
    return intf;
   }
  }

  public ImplementsAttribute(Type i) {
   intf = i;
  }
 }

 public class BaseImplementor {
  public object ImplClass;
 }

 public class ImplBuilder {
  
  private class Implementation {
   public Type Interface;
   public FieldInfo Field;
   public Implementation(Type i, FieldInfo f) {
    Interface = i;
    Field = f;
   }
  }

  private Assembly CompiledAssembly;

  public ImplBuilder(Type ic) {
   ArrayList il = new ArrayList();

   //retreiving list of implementation fields
   foreach(FieldInfo fi in ic.GetFields()) {
    ImplementsAttribute ia = (ImplementsAttribute) Attribute.
      GetCustomAttribute(fi,typeof(ImplementsAttribute));
    if(ia == null)
     throw new ArgumentException("No any fields marked [Implements] found");
    else {
     il.Add(new Implementation(ia.Interface,fi));
    }
   }

   //Building implementor class
   StringBuilder csrc = new StringBuilder();
   csrc.Append("namespace ConnectingImpl.DynamicAssembly {\n");
   csrc.Append(" public class "+ic.Name+"Implementor : ConnectingImpl.BaseImplementor");
   foreach(Implementation impl in il)
    csrc.Append(","+impl.Interface.FullName);
   csrc.Append(" {\n");
   foreach(Implementation impl in il)
    foreach(MethodInfo mi in impl.Interface.GetMethods()) {
     ParameterInfo[] pia = mi.GetParameters();
     StringBuilder dl = new StringBuilder(), cl = new StringBuilder();
     foreach(ParameterInfo pi in pia) {
      if(dl.Length > 0) {
       dl.Append(", ");
       cl.Append(", ");
      }
      dl.Append(pi.ParameterType.FullName+" "+pi.Name);
      cl.Append(pi.Name);
     }
     csrc.Append("  public ");
     if(mi.ReturnType.FullName != "System.Void")
      csrc.Append(mi.ReturnType.FullName);
     else
      csrc.Append("void");
     csrc.Append(" "+mi.Name+"(");
     csrc.Append(dl);
     csrc.Append(") {\n");
     if(mi.ReturnType.FullName != "System.Void")
      csrc.Append("   return ");
     else
      csrc.Append("   ");
     csrc.Append("(("+ic.FullName+") ImplClass)."+impl.Field.Name+"."+mi.Name+"(");
     csrc.Append(cl);
     csrc.Append(");\n");
     csrc.Append("  }\n");
    }
   csrc.Append(" }\n");
   csrc.Append("}");

   //Compile class
   ICodeCompiler cc = new Microsoft.CSharp.CSharpCodeProvider().CreateCompiler();
   CompilerParameters cp = new CompilerParameters();
   cp.ReferencedAssemblies.Add(ic.Assembly.Location);
   cp.GenerateInMemory = true;
   CompilerResults cr = cc.CompileAssemblyFromSource(cp,csrc.ToString());

   Console.WriteLine(cr.NativeCompilerReturnValue);
   CompiledAssembly = cr.CompiledAssembly;
  }

  public object CreateInstance(object ic) {
   BaseImplementor i = (BaseImplementor) CompiledAssembly.CreateInstance(
     "ConnectingImpl.DynamicAssembly."+ic.GetType().Name+"Implementor");
   i.ImplClass = ic;
   return i;
  }

 }

}
... << RSDN@Home 1.0 alpha 12 (developers build)>>
AVK Blog
Re[7]: C# ликбез
От: Andy77 Ниоткуда  
Дата: 16.10.02 21:15
Оценка:
Здравствуйте AndrewVK, Вы писали:

AVK>Здравствуйте Andy77, Вы писали:


[skipped]

Очень интересно, спасибо, буду разбираться
Re[5]: C# ликбез
От: Eugene Hrulev Россия  
Дата: 17.10.02 01:08
Оценка:
Здравствуйте Igor Trofimov, Вы писали:

A>>Меня удивляет, что нигде в современных языках не встречается такая конструкция

A>>вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.

IT>Нечто очень близкое есть в Delphi'йском ObjectPascal. Только там надо для каждого метода реализуемого интерфейса указать какой объект и какой его метод подставлять.


Такое там тоже есть (пометодно). Но есть и следующее:

создается проперть, возвращающая наследуемый интерфейс и декларируется, что именно она (проперть) и будет этот интерфейс реализовывать. Без шаманских штучек типа вызова компилятора.

С уважением, Евгений.
Re[8]: C# ликбез
От: Eugene Hrulev Россия  
Дата: 17.10.02 01:13
Оценка:
Здравствуйте IT, Вы писали:

IT>Здравствуйте VladD2, Вы писали:


...
VD>>За одно нужно добавить шаблоны, const для параметров и локальных переменных... Куда? Думаю ты понял.

IT>Кстати, в MC++ кое что уже из этого есть (я про использование реализации). В нём, если класс или его предки имеет метод с таким же названием и сигнатурой, то он по умалчанию используется для имплементации метода интерфейса.


Да, с одной стороны это зачастую очень удобно, а с другой стороны — немного противоречит общей тенденции шарпа заставлять программиста "явно выражать свои намерения".

С уважением, Евгений.
Re[6]: Помогите выбрать базу!
От: vedmed  
Дата: 17.10.02 11:47
Оценка:
Здравствуйте Eugene Hrulev, Вы писали:

EH>Здравствуйте Igor Trofimov, Вы писали:


A>>>Меня удивляет, что нигде в современных языках не встречается такая конструкция

A>>>вроде бы, и код чистый, понятный, хорошая возможность code reuse, присутствует наследование реализации, множественное наследование, как таковое, отсутствует... нет в жизни счастья.

IT>>Нечто очень близкое есть в Delphi'йском ObjectPascal. Только там надо для каждого метода реализуемого интерфейса указать какой объект и какой его метод подставлять.


EH>Такое там тоже есть (пометодно). Но есть и следующее:


EH>создается проперть, возвращающая наследуемый интерфейс и декларируется, что именно она (проперть) и будет этот интерфейс реализовывать. Без шаманских штучек типа вызова компилятора.


Подробности на
http://nps.vnet.ee/ftp/Docs/Delphi/D5/oplg/objintrf.html#7680
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.