2

一般に、基本クラスでのリフレクションは、いくつかの有益で有用な目的に使用できますが、ここでは岩と困難な場所の間にいる場合があります... リフレクションを使用するか、パブリック ファクトリ クラスを実際に公開する必要がある場合に公開します。意味的に言えばプライベートです(つまり、誰でも使用できるべきではありません)。私はいくつかのコードがここにあると思います:

public abstract class SingletonForm<TThis> : Form 
    where TThis : SingletonForm<TThis>
{
    private static TThis m_singleton;
    private static object m_lock = new object();
    private static ISingletonFormFactory<TThis> m_factory;

    protected SingletonForm() { }

    public static TThis Singleton
    {
        get
        {
            lock (m_lock)
            {
                if (m_factory == null)
                {
                    foreach (Type t in typeof(TThis).GetNestedTypes(BindingFlags.NonPublic))
                    {
                        foreach (Type i in t.GetInterfaces())
                        {
                            if (i == typeof(ISingletonFormFactory<TThis>))
                                m_factory = (ISingletonFormFactory<TThis>)Activator.CreateInstance(t);
                        }
                    }

                    if (m_factory == null)
                        throw new InvalidOperationException(string.Format(
                            CultureInfo.InvariantCulture,
                            "{0} does not implement a nested ISingletonFormFactory<{0}>.",
                            typeof(TThis).ToString()));
                }

                if (m_singleton == null || m_singleton.IsDisposed)
                {
                    m_singleton = m_factory.GetNew();
                }

                return m_singleton;
            }
        }
    }
}

さて、このコードは私にとってはうまくいきますが、それは恐ろしいクラッジおよび/または本当に悪い考えですか? もう 1 つのオプションは、Factory の型を型パラメーターとして渡すことですが、可視性の制限により、Factory クラスは public である必要があります。

4

4 に答える 4

3

ジェネリックを扱うときは、頻繁にリフレクションを使用する必要があります。その点では、あなたは大丈夫だと思います。

とはいえ、ここには 2 つの形式のコードの匂いが見られます。ただし、コードのサニテーションが原因である可能性があるため、それらについてコメントします。

まず、静的プロパティは一般的なアイテムです。私はこれがコンパイルさえされないことを 99.999% 確信しています。もしそうなら、それは悪い形です。

次に、 への呼び出しごとに新しいインスタンスを返しているように見えますBar。これは、getter の悪い形式とも見なされます。代わりに、CreateBar() などのメソッドを使用します。

于 2009-06-30T01:32:52.427 に答える
1

この状況は、使用する型を明示的に定義できるカスタム属性でもうまく処理できます。

[AttributeUsage( AttributeTargets.Class, AllowMultiple = false )]
public sealed class SingletonFactoryAttribute : Attribute
{
    public Type FactoryType{get;set;}   
    public SingletonFormAttribute( Type factoryType )
    { 
        FactoryType = factoryType; 
    }
}

シングルトン プロパティは次のようになります

public static TThis Singleton
{
    get
    {
        lock (m_lock)
        {
            if (m_factory == null)
            {
                var attr = Attribute.GetCustomAttribute( 
                               typeof( TThis ), 
                               typeof( SingletonFactoryAttribute ) ) 
                               as SingletonFactoryAttribute;

                if (attr == null)
                    throw new InvalidOperationException(string.Format(
                        CultureInfo.InvariantCulture,
                        "{0} does not have a SingletonFactoryAttribute.",
                        typeof(TThis).ToString()));

                m_factory = Activator.CreateInstance( attr.FactoryType );
            }

            if (m_singleton == null || m_singleton.IsDisposed)
            {
                m_singleton = m_factory.GetNew();
            }

            return m_singleton;
        }
    }
} 
于 2009-06-30T15:10:14.513 に答える
0

参考までに、以下はから削減できます

foreach (Type i in t.GetInterfaces())
{
    if (i == typeof(ISingletonFormFactory<TThis>))
        m_factory = (ISingletonFormFactory<TThis>)Activator.CreateInstance(t);
}

if( typeof( ISingletonFormFactory<TThis> ).IsAssignableFrom( t ) )
    m_factory = Activator.CreateInstance( t ) as ISingletonFormFactory<TThis>;
于 2009-06-30T02:34:16.033 に答える
0

可能であれば、リフレクションを回避できるのであれば、リフレクションの使用を避けたいと思います。

これを行うには、Abstract Factory パターンを使用して、状況に応じてパブリック ファクトリ タイプを直接公開するという問題を回避することができます。

ウィキペディアの例で (Java で) 説明すると、ファクトリ クラスが実装するファクトリ インターフェイスを作成し、コード内に必要なファクトリを生成し、それをファクトリ インターフェイスとして返すというものがあります。

これを行う別の方法は、抽象ファクトリのインターフェイスではなく抽象クラスを作成し、必要な型ファクトリを返すためにこの抽象クラス内に静的メソッドを作成することです。

于 2009-06-30T01:41:40.537 に答える