2016-10-11 3 views
-3

Я разрабатываю класс, который создает экземпляр класса (с использованием Activator.CreateInstance), который указан для класса (либо как параметр типа, либо как параметр для конструктора), поэтому довольно бессмысленно создавать экземпляр класса, когда класс создает экземпляр в любом случае, поэтому переход к типу с использованием дженериков имеет смысл. Например.Доля кода между классом и общим классом

var foo = new Foo<Bar>(); 

Однако это делает класс нельзя использовать во время выполнения Тхо, так как параметр типа объявлен во время компиляции.

Чтобы использовать это во время выполнения, конструктор должен принять параметр в качестве аргумента. Например.

var foo = new Foo(new Bar()); 

Остальные кода в классах одни и те же, так что если это были два разных классов, то было бы много повторяющегося кода.

Вопросы:

  • Как разделить код и избежать дублирования кода?
  • Может (и должен) это быть двумя конструкторами того же класса?
  • Я принимаю неправильный подход? Может быть new Foo(typeof(Bar))?
+1

Пожалуйста, объясните, в чем заключается цель этого. В настоящее время это неясно/слишком широко. Я предполагаю, что для «кода обмена» - состав/наследование. Два конструктора - да, возможно. 'typeof (Bar)' - это что-то другое - зависит от того, чего вы хотите от –

+0

Мне любопытно, как выглядит ваша реализация. Из вопроса это больше похоже на кандидата на наследование, чем на общий. Или, если 'Foo' зависит от' Bar', тогда общие свойства/методы могут вызвать вызов другого и избегать дублирования. – Theo

+4

* Я разрабатываю класс, который создает экземпляр класса, который указан для класса (либо как параметр типа, либо как параметр для конструктора), поэтому совершенно бессмысленно создавать экземпляр класса, когда класс создает экземпляр в любом случае, поэтому для прохождения в типе с использованием дженериков имеет смысл. * ... да? –

ответ

0

Хорошо, теперь я понял это!

Я делаю два отдельных класса; один нормальный и один общий. Общий наследует от нормального и имеет общий конструктор, который вызывает конструктор из базового класса.

Обычный класс нуждается в конструкторе, который принимает в качестве аргумента Type (этот конструктор не должен быть public, это может быть protected). Этот конструктор вызывается из общего класса.

public class Foo 
    { 
     private readonly object _bar; 

     public Foo(Bar bar) : this(bar.GetType()) 
     { 
     } 

     protected Foo(Type bar) 
     { 
      _bar = Activator.CreateInstance(bar); 
     } 

     public void Write() 
     { 
      Console.WriteLine(_bar); 
     } 
    } 

    public class Foo<T> : Foo 
    { 
     public Foo() : base(typeof(T)) 
     { 
     } 
    } 

Теперь я могу создать экземпляр класса, используя обычный класс или общий класс.

var foo1 = new Foo(new Bar()); 
    foo1.Write(); 

    var foo2 = new Foo<Bar>(); 
    foo2.Write(); 
+0

Почему конструктор Foo (Bar bar) создает новый экземпляр? Вы можете просто _bar = bar. –

+0

@ R.Rusev, потому что именно этот класс предназначен для этого. Однако я отредактировал сообщение, чтобы переписать его так, чтобы только один конструктор выполнил эту задачу, и теперь он вызывает другой конструктор, чтобы избежать дублирования кода. – Fred

+0

Итак, цель класса (Foo) - всегда создавать новый экземпляр указанного класса (Bar), даже если это делается путем предоставления существующего экземпляра этого класса (Bar) конструктору класса (Foo)? –

0

Я попытался решить вашу проблему с помощью специального конструктора. Это не работает. Это потому, что C# рассматривает Foo <Bar> и Foo <Int> Как совершенно другие типы. Поэтому конструктор, который получает тип, не работает.

Следующее решения было введение Generic статического класса, чтобы помочь с этим:

[TestClass] 
public class FooBarTest 
{ 
    [TestMethod] 
    public void TestFooBar() 
    { 
     var foo = new Foo<Bar>(); 
     var foo2 = Foo.CreateFoo(new Bar()); 
     Assert.AreEqual(foo.GetType(), foo2.GetType()); 
    } 
} 


public class Foo<T> 
{ 
    public Foo() 
    { 

    } 

    public Foo(T obj) 
    { 

    } 
} 

public static class Foo 
{ 
    public static Foo<TType> CreateFoo<TType>(TType obj) 
    { 
     return new Foo<TType>(obj); 
    } 
} 

public class Bar 
{ 

} 

Это будет означать, что статический класс Foo (не дженерик) будет создавать объект для вас. Тест единицы включен, чтобы проверить эффект!

Смежные вопросы