98

C++ テンプレートでは、特定の型パラメーターがデフォルトであることを指定できます。つまり、明示的に指定しない限り、型 T を使用します。

これはC#で実行または近似できますか?

私は次のようなものを探しています:

public class MyTemplate<T1, T2=string> {}

そのため、明示的に指定されていない型のインスタンスT2:

MyTemplate<int> t = new MyTemplate<int>();

本質的に次のようになります。

MyTemplate<int, string> t = new MyTemplate<int, string>();

最終的には、かなり広く使われているテンプレートがあるケースを見ていますが、型パラメータを追加して拡張することを検討しています。サブクラス化できたと思いますが、この流れで他のオプションがあるかどうかに興味がありました。

4

6 に答える 6

82

サブクラス化は最良のオプションです。

メインのジェネリック クラスをサブクラス化します。

class BaseGeneric<T,U>

特定のクラスで

class MyGeneric<T> : BaseGeneric<T, string>

これにより、ロジックを 1 か所 (基本クラス) に簡単に保持できるだけでなく、両方の使用オプションを簡単に提供できます。クラスによっては、これを実現するために必要な余分な作業はおそらくほとんどありません。

于 2009-04-01T23:53:38.797 に答える
22

1 つの解決策は、サブクラス化です。代わりに使用するもう 1 つの方法は、ファクトリ メソッド (var キーワードと組み合わせたもの) です。

public class MyTemplate<T1,T2>
{
     public MyTemplate(..args..) { ... } // constructor
}

public static class MyTemplate{

     public static MyTemplate<T1,T2> Create<T1,T2>(..args..)
     {
         return new MyTemplate<T1, T2>(... params ...);
     }

     public static MyTemplate<T1, string> Create<T1>(...args...)
     {
         return new MyTemplate<T1, string>(... params ...);
     }
}

var val1 = MyTemplate.Create<int,decimal>();
var val2 = MyTemplate.Create<int>();

上記の例val2では、タイプであり、それから派生したタイプMyTemplate<int,string> ではありません。

タイプclass MyStringTemplate<T>:MyTemplate<T,string>は と同じタイプではありませんMyTemplate<T,string>。これは、特定のシナリオでいくつかの問題を引き起こす可能性があります。たとえば、のインスタンスをMyTemplate<T,string>to にキャストすることはできませんMyStringTemplate<T>

于 2014-12-15T16:34:14.260 に答える
15

そのようにクラス Overload を作成することもできます

public class MyTemplate<T1, T2> {
    public T1 Prop1 { get; set; }
    public T2 Prop2 { get; set; }
}

public class MyTemplate<T1> : MyTemplate<T1, string>{}
于 2015-12-02T02:23:07.537 に答える
10

C# はそのような機能をサポートしていません。

あなたが言ったように、それをサブクラス化することはできますが(封印されていない場合、すべてのコンストラクター宣言を複製します)、それはまったく別のものです。

于 2009-04-01T23:54:56.967 に答える
3

残念ながら、C# はあなたがしようとしていることをサポートしていません。パラメーターの既定の型が一般的な制約に準拠する必要があり、CLR が型の安全性を確保しようとしたときに頭痛の種になる可能性が高いことを考えると、これを実装するのは難しい機能です。

于 2009-04-01T23:57:09.990 に答える
1

型をインターフェースにオーバーロードしたい場合は、次のようにすることができます: 例:

public interface ISRD<TItem, TId>
{
    Task SaveAsync(TItem item);
    Task<TItem> GetAsync(TId id);
    Task DeleteAsync(TItem item);
}

public interface ISRD<TItem>: ISRD<TItem, Guid> { }
于 2022-01-18T00:35:37.633 に答える