2016-10-11 11 views
-3

クラスに指定されているクラスのインスタンスを作成しています(型パラメータまたはコンストラクタのパラメータのいずれかとして)クラスがインスタンスを作成するときにクラスのインスタンスを作成するのはむしろ意味がないため、ジェネリックを使用して型を渡すことは意味があります。例えば。クラスと汎用クラスのコードを共有する

var foo = new Foo<Bar>(); 

しかし、コンパイル時に型パラメータが宣言されているため、これにより実行時にクラスを使用できなくなります。

これを実行時に使用するには、コンストラクタが引数として引数を取る必要があります。例えば。クラスで

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

コードの残りの部分は、しかし同じなので、これは2つの異なるクラスであることをした場合、重複したコードの多くが存在することになります。

質問:

  • どのように私はコードを共有し、コードの重複を避けるのですか?
  • これは、同じクラスの2つのコンストラクタとすることができますか?
  • 私は間違ったアプローチをとっていますか?たぶんnew Foo(typeof(Bar))
+1

現在、それは明確ではない/広すぎます。私は、 "共有コード" - 構成/継承を想定しています。 2つのコンストラクタ - はい、可能です。 'typeof(Bar)' - これは他のものです - あなたがしたいことに依存します –

+0

あなたの実装がどのように見えるか不思議です。この質問から、これは一般的なものよりも継承の候補に似ています。あるいは、 'Foo'が' Bar'に依存している場合、共通プロパティ/メソッドは他のものを呼び出すことができ、複製を避けることができます。 – Theo

+4

*クラスに指定されているクラスのインスタンスを作成するクラスを開発しています(型パラメータまたはコンストラクタのパラメータとして)。そのため、クラスのインスタンスを作成するのは無意味ですとにかくインスタンスを生成するので、ジェネリックを使って型を渡すのが理にかなっています。 –

答えて

0

さて、私は今これを理解しました!

私は2つの別々のクラスを作成します。 1つの通常と1つの一般的な。一般的なものは通常のものを継承し、基本クラスからコンストラクタを呼び出すジェネリックコンストラクタを持ちます。

普通のクラスでは、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にすることができます。 –

+0

@ R.Rusevこれは、この特定のクラスが行うように設計されているためです。しかし、投稿を編集して、コンストラクタがそのタスクを実行するように書き直しました。そして、コードの重複を避けるために、もう一方のコンストラクタを呼び出します。 – Fred

+0

したがって、クラス(Foo)のコンストラクタにそのクラス(Bar)の既存のインスタンスを渡しても、指定されたクラス(Bar)の新しいインスタンスを常に作成することが、クラス(Foo)の目的ですか? –

0

カスタムコンストラクタで問題が発生しました。うまく行かなかった。これは、C#がFoo <Bar>とFoo <Intを扱うためです。>他のタイプとまったく同じです。したがって、型を受け取るコンストラクタは機能しません。

次のソリューションは、これを支援するためにジェネリック静的クラスの紹介だった:

[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(ノージェネリック)はあなたのためのオブジェクトを作成することを意味します。効果をチェックするユニットテストが含まれています!

関連する問題