Вопрос по C#
От: jonny210  
Дата: 11.07.06 06:13
Оценка:
в delphi можно написать так:
type
  TBaseObj = class;
  TBaseObjClass = class of TBaseObj;
  
  TMyObj1 = class(TBaseObj)
  end;

  TMyObj2 = class(TBaseObj)
  end;
  


procedure xxx1;
begin
  xxx2(TMyObj1);
end;

procedure xxx2(obj_class: TBaseObjClass);
var
  Obj: TBaseObj;
begin
  Obj := obj_class.Create;
  ....
end;


т.е. в функции xxx2 создается объект тип которого передается в функцию параметром. Собственно вопрос, как сие организовать в C#? Это очень важно... Помогите кто может.
Re: Вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.07.06 06:56
Оценка: 1 (1) +1
Здравствуйте, jonny210. Попробуйте так:

using System;

public interface IFruit
{
    void Eat();
}

public class Apple : IFruit
{
    public void Eat()
    {
        Console.WriteLine("Вкусное яблоко!");
    }
}

public class Pear : IFruit
{
    public void Eat()
    {
        Console.WriteLine("Вкусная груша!");
    }
}
public class Program
{
    public static void Main()
    {
        Type[] fruitTypes = new Type[]{typeof(Apple), typeof(Pear)};
        foreach(Type fruitType in fruitTypes)
        {
            IFruit fruit = CreateFruit(fruitType);
            fruit.Eat();
        }
    }
    
    public static IFruit CreateFruit(Type ofThisType)
    {
        return (IFruit) Activator.CreateInstance(ofThisType);
    }
}
Re: Вопрос по C#
От: vhonest  
Дата: 11.07.06 06:56
Оценка:
Здравствуйте, jonny210, Вы писали:

J>т.е. в функции xxx2 создается объект тип которого передается в функцию параметром. Собственно вопрос, как сие организовать в C#? Это очень важно... Помогите кто может.


Вот, например, как можно создать объекта, когда его тип известен только в рантайме
            Type t = typeof(System.Text.StringBuilder);
            System.Reflection.ConstructorInfo ci = t.GetConstructor(Type.EmptyTypes); // конструктор без параметров
            object o = ci.Invoke(null);  // вызов конструктора

            Console.WriteLine(o.GetType());


А вообще я бы писал на том языке, который лучше знаю.
.NET позволяет использовать типы, реализованные на одном NET-совместимом языке, из другого языка
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Вопрос по C#
От: Дьяченко Александр Россия  
Дата: 11.07.06 07:09
Оценка: 1 (1)
Здравствуйте, jonny210, Вы писали:

J>в delphi можно написать так:

J>
J>type
J>  TBaseObj = class;
J>  TBaseObjClass = class of TBaseObj;
  
J>  TMyObj1 = class(TBaseObj)
J>  end;

J>  TMyObj2 = class(TBaseObj)
J>  end;
  


J>procedure xxx1;
J>begin
J>  xxx2(TMyObj1);
J>end;

J>procedure xxx2(obj_class: TBaseObjClass);
J>var
J>  Obj: TBaseObj;
J>begin
J>  Obj := obj_class.Create;
J>  ....
J>end;
J>

J>т.е. в функции xxx2 создается объект тип которого передается в функцию параметром. Собственно вопрос, как сие организовать в C#? Это очень важно... Помогите кто может.

Классы:

class BaseObj {}
class MyObj1: BaseObj {}
class MyObj2: BaseObj {}

Ближе всего наверно будет следующий вариант:

class Program
{
    void xxx1()
    {
        xxx2(typeof(MyObj1));
    }
    
    void xxx2(Type objType)
    {
        BaseObj obj = (BaseObj)Activator.CreateInstance(objType);
    }
}

Или вот такой:

class Program
{
    void xxx1()
    {
        xxx2(typeof(MyObj1));
    }
    
    void xxx2<T>() where T: BaseObj
    {
        BaseObj obj = Activator.CreateInstance<T>();
    }
}
... << RSDN@Home 1.2.0 alpha rev. 654>>
Re[2]: Вопрос по C#
От: jonny210  
Дата: 11.07.06 07:13
Оценка:
Здравствуйте, vhonest, Вы писали:

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


J>>т.е. в функции xxx2 создается объект тип которого передается в функцию параметром. Собственно вопрос, как сие организовать в C#? Это очень важно... Помогите кто может.


V>Вот, например, как можно создать объекта, когда его тип известен только в рантайме

V>
            Type t = typeof(System.Text.StringBuilder);
V>            System.Reflection.ConstructorInfo ci = t.GetConstructor(Type.EmptyTypes); // конструктор без параметров
V>            object o = ci.Invoke(null);  // вызов конструктора

V>            Console.WriteLine(o.GetType());
V>


V>А вообще я бы писал на том языке, который лучше знаю.

V>.NET позволяет использовать типы, реализованные на одном NET-совместимом языке, из другого языка

Спасибо что откликнулись. Но есть проблема. Параметры конструктора. когда я объявляю переменную так:
var o: class of TMyObj;

при создании объекта компилятор точно знает какие параметры я должен передать конструктору. Если я изменю конструктор объекта код просто не скомпилируется... Мне не нужно полностью динамическое создание объекта...

И еще вопрос. При наследовании объектов в C# конструктор почему то не наследуется...(((
class Obj1
{
    public Obj1(int x);
}

class Obj2 : Obj1
{
}
...
Obj2 obj = new Obj2(10);

Последняя строчка не скомпилируется потом что Obj2 ничего незнает о конструкторе из Obj1... Неужели из обязательно нужно переобъявлять?
Re[3]: Вопрос по C#
От: desco США http://v2matveev.blogspot.com
Дата: 11.07.06 07:21
Оценка: 1 (1)
Здравствуйте, jonny210, Вы писали:

J>И еще вопрос. При наследовании объектов в C# конструктор почему то не наследуется...(((

J>
J>class Obj1
J>{
J>    public Obj1(int x);
J>}

J>class Obj2 : Obj1
J>{
J>}
J>...
J>Obj2 obj = new Obj2(10);
J>

J>Последняя строчка не скомпилируется потом что Obj2 ничего незнает о конструкторе из Obj1... Неужели из обязательно нужно переобъявлять?


17.10.1 Constructor initializers
All instance constructors (except those for class object) implicitly include an invocation of another
instance constructor immediately before the constructor-body. The constructor to implicitly invoke is
determined by the constructor-initializer:

• An instance constructor initializer of the form base(argument-listopt) causes an instance constructor
from the direct base class to be invoked. That constructor is selected using argument-list and the
overload resolution rules of §14.4.2. The set of candidate instance constructors consists of all accessible
instance constructors declared in the direct base class, or the default constructor (§17.10.4), if no
instance constructors are declared in the direct base class. If this set is empty, or if a single best instance
constructor cannot be identified, a compile-time error occurs.

...
<skipped>
...
If an instance constructor has no constructor initializer, a constructor initializer of the form base() is
implicitly provided. [Note: Thus, an instance constructor declaration of the form

C(…) {…}

is exactly equivalent to
C(…): base() {…}

end note]

Re[3]: Вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.07.06 07:32
Оценка:
Здравствуйте, jonny210, Вы писали:

J>И еще вопрос. При наследовании объектов в C# конструктор почему то не наследуется...(((

J>... Неужели из обязательно нужно переобъявлять?

Inheritance means that a class implicitly contains all members of its direct base class, except for the instance constructors, destructors and static constructors of the base class. (MSDN)


Да, обязательно. Конструкторы не наследуются. Но Вы можете явно делегировать вызов конструктору базового класса.

class Obj1
{
    protected int _x;
    public Obj1(int x)
    {
        _x = x;
    }
}

class Obj2 : Obj1
{
    public Obj2(int x) : base(x)
    {
    }
}
Re[3]: Вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.07.06 07:34
Оценка:
Здравствуйте, jonny210, Вы писали:

J>Но есть проблема. Параметры конструктора. когда я объявляю переменную так:

J>
J>var o: class of TMyObj;
J>

J>при создании объекта компилятор точно знает какие параметры я должен передать конструктору. Если я изменю конструктор объекта код просто не скомпилируется... Мне не нужно полностью динамическое создание объекта...

Опишите подробнее, какое поведение Вы бы хотели получить.
Re[4]: Вопрос по C#
От: jonny210  
Дата: 11.07.06 07:47
Оценка:
Здравствуйте, nikov, Вы писали:

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


J>>Но есть проблема. Параметры конструктора. когда я объявляю переменную так:

J>>
J>>var o: class of TMyObj;
J>>

J>>при создании объекта компилятор точно знает какие параметры я должен передать конструктору. Если я изменю конструктор объекта код просто не скомпилируется... Мне не нужно полностью динамическое создание объекта...

N>Опишите подробнее, какое поведение Вы бы хотели получить.


Есть базовый класс, и куча наследников...
public class Base
{
    public Base(int x)
    {
    ...
    }
}

public class Child1 : Base
{
    public Child1(int x) : base (x)
    {
    }
}
  
public class Child2 : Base
{
    public Child2(int x) : base (x)
    {
    }
}
  
public class Child3 : Base
{
    public Child3(int x) : base (x)
    {
    }
}


теперь есть процедура которая должна создавать объект класс которого передается параметром
public string xxx(Base class_type)
{
    Base obj = class_type(10);
    obj.GetType().ToString();
}


я знаю что так делать нельзя, но как это сделать в C# я не знаю...
и из основного кода я делаю
    xxx(Child1);
    xxx(Child2);
    xxx(Child3);


Вот такая у меня заморочка... В Delphi это все элементарно делается...
Re[5]: Вопрос по C#
От: nikov США http://www.linkedin.com/in/nikov
Дата: 11.07.06 08:09
Оценка:
using System;

public class Base
{
    protected int _x;
    public Base(int x)
    {
        _x = x;
    }
    public void GetX()
    {
        Console.WriteLine(_x);
    }
}

public class Child1 : Base
{
    public Child1(int x) : base(x)
    {
    }
}

public class Child2 : Base
{
    public Child2(int x) : base(x)
    {
    }
}

public class Child3 : Base
{
    public Child3(int x) : base(x)
    {
    }
}

public class Program
{
    public static void Main()
    {
        Type[] childTypes = new Type[]{typeof(Child1), typeof(Child2), typeof(Child3)};
        foreach(Type type in childTypes)
        {
            Base child = xxx(type);
            child.GetX();
            Console.WriteLine(child.GetType());
        }
    }
    
    public static Base xxx(Type childType)
    {
        return (Base) Activator.CreateInstance(childType, 10); /* второй параметр будет передан в конструктор */
    }
}
Вопрос по C#
От: Аноним  
Дата: 11.07.06 06:35
Оценка:
MSDN Вам поможет.
смотрите Type.GetConstructor, ConstructorInfo.Invoke


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Вопрос по C#
От: Аноним  
Дата: 11.07.06 06:51
Оценка:
class App
{
static void Main(string[] args)
{
Print(typeof(C));
Print(typeof(C1));
Print(typeof(C2));
}
static void Print(Type t)
{
object obj = Activator.CreateInstance(t);
(obj as C).Print();
}
}
class C
{
public virtual void Print()
{
Console.WriteLine("C");
}
}
class C1 : C
{
public override void Print()
{
Console.WriteLine("C1");
}
}
class C2 : C
{
public override void Print()
{
Console.WriteLine("C2");
}
}



данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[4]: Вопрос по C#
От: Аноним  
Дата: 11.07.06 08:07
Оценка:
Насколько я понимаю, здесь лучше использовать паттерн "Фабрика".


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.