2012-01-16 5 views
2

私は非ジェネリックビルダークラスで暗黙の演算子を使用する場合、すべてのものはOKです:これは一般的な暗黙の演算子を使って何が問題になっていますか?

public class ReligionBuilder 
{ 
    private Religion _religion; 

    public ReligionBuilder() 
    { 
     _religion = new Religion(){//some codes} 

    } 

    public ReligionBuilder AddToRepository() 
    { 
     Repository<Religion>.Add(_religion); 
     return this; 
    } 
    public Religion Build() 
    { 
     return _religion; 
    } 

    public static implicit operator Religion(ReligionBuilder _builder) 
    { 
     return _builder.Build(); 

    } 
} 

私はそれを使用することができます。

Religion religion=new ReligionBuilder().AddToRepository(); 

が、この演算子は、何かが間違っている一般的なクラスである場合:

public abstract class DataTestBuilderBase<T> : IDataTestBuilder<T> 
{ 
    protected T TestData { get; set; } 

    public virtual T Build() 
    { 
     return TestData; 
    } 

    public abstract IDataTestBuilder<T> AddToRepository(); 
    public abstract IDataTestBuilder<T> WithDefault(); 

    public static implicit operator T(DataTestBuilderBase<T> builder) 
    { 
     return builder.Build(); 
    } 
} 


public class PersonDataTestBuilder : DataTestBuilderBase<Person> 
{ 
    private Person _person; 

    public PersonDataTestBuilder() 
    { 
     //some codes 
    } 
    public override IDataTestBuilder<Person> AddToRepository() 
    { 
     //some codes 
     return this; 
    } 
} 

用法:

PersonDataTestBuilder _testBuilder = new PersonDataTestBuilder(); 
     Person person = _testBuilder.AddToRepository(); 

エラー:IDataTestBuilderをPersonに変換できません

何が問題なのですか?

+0

私たちは独自の実装ビルダを使い始めましたが、http://nbuilder.org/を使用して終了しました。これは本当にうれしく、多くの機能を備えています。 –

答えて

0

AddToRepositoryだけIDataTestBuilder<Person>(コンパイル時の戻り値の型の面で)返します - とからそのPersonへの暗黙的な変換はありません。抽象メソッドの戻り値の型をDataTestBuilderBase<T>に変更すると、うまくいくはずですが、とにかく暗黙の変換を使用したくないですが。私は一般に、暗黙的な変換を提供することにかなり慎重です - 彼らはここでそう信じているように、しばしばコードをあまり明確にできません。

実際にビルダーにAddToRepositoryを提供する必要がありますか?とにかく?それは、ビルダーのために不適切な行為のように感じている - 私は期待:

Person person = new PersonBuilder { /* properties */ } 
        .Build() 
        .AddToRepository(); 

EDITを:ちょうど私がAddToRepositoryの戻り値の型を変更することについて、何を意味するかを示すために、ここに実証する短いが完全なプログラムです。それはうまく動作します。

using System; 

public abstract class BuilderBase<T> 
{ 
    public abstract T Build(); 
    public abstract BuilderBase<T> AddToRepository(); 

    public static implicit operator T(BuilderBase<T> builder) 
    { 
     return builder.Build(); 
    } 
} 

public class TestBuilder : BuilderBase<string> 
{ 
    public override string Build() 
    { 
     return "Built by Build()"; 
    } 

    public override BuilderBase<string> AddToRepository() 
    { 
     return this; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     string x = new TestBuilder().AddToRepository(); 
     Console.WriteLine(x); 
    } 
} 
+0

u r right、それはビルダーにはいけません。 – Adrakadabra

+0

@Adrakadabra:それは本当にありますが、私の編集は短いが完全な例です。あなたが間違っていたことを詳細な説明なしに言うのは難しいですが、その原則はうまくいくはずです。 –

+0

あなたは正しいです、私の問題は、DataTestBuilderBase がIDataTestBuilder を実装していて、その戻り値の型が正しくありませんでした – Adrakadabra

関連する問題