3

私はこのように定義された基本的な DataTag クラスを持っています:

public abstract class DataTag<TRaw, TVal>
{
    public abstract TVal Value { get; }
    public TRaw RawValue { get; set; }
    public string Name { get; private set; }
    public string Desc { get; private set; }
}

ここで、TRaw はデバイスから取得した生データであり、TVal は「フォーマットされた」値です。

だから私は同じデバイスから2つのタグを持っているかもしれません:

DataTag t1 = DataTag.Create<ushort,int>();
DataTag t2 = DataTag.Create<ushort[],float()>;

今、私は一般的なタグのリストを含むべきクラスを持っています

private IEnumerable<DataTag<?,?> _tags();

もちろん、C# は同じリストで異なる種類のジェネリックを受け入れませんが、これは私が達成したいことです。そのためのヒントはありますか?

4

1 に答える 1

4

一般的なアプローチの 1 つは、非ジェネリック基本クラスを宣言することです。もちろん、データへの厳密に型指定されたアクセスは提供されませんが、プレーンobjectバージョンと名前/説明を取得できる可能性があります。

public abstract class DataTag
{
    public string Name { get; private set; }
    public string Description { get; private set; }
    public abstract object WeakValue { get; }
    public abstract object WeakRawValue { get; }
}

public abstract class DataTag<TRaw, TVal> : DataTag
{
    public abstract TVal Value { get; }
    public TRaw RawValue { get; set; }

    public override object WeakValue { get { return Value; } }
    public override object WeakRawValue { get { return RawValue; } }
}

次に、リストは単なるIEnumerable<DataTag>.

ノート:

  • 「弱く型付けされた」プロパティには別の名前を付けました。andを使用して、ジェネリック型で( を使用して) それらを再宣言することもできますが、それは他の方法では首の痛みです。可能であれば、名前の衝突を避けてください。ValueRawValuenew
  • 私は getter のみを提供しましたWeakRawValue- setter も提供し、ジェネリック型内でキャストすることもできますが、それは私には醜く感じます。個人的には、セッターを完全に取り除き、値をコンストラクターの引数として渡し、型を不変に近づけようとします。(ジェネリック型引数のいずれかがそれ自体が可変型である場合、「適切に」不変になることはありませんが、何もないよりはましです...)
于 2013-03-09T11:57:05.920 に答える