ジェネリック型がtype1 or type2であることをジェネリック関数を宣言する方法はありますか?
例:
public void Foo<T>(T number)
{
}
Tをintまたはlongに制約できますか
generic constraint を使用して各ジェネリック引数Tのタイプを制限することもできますが、残念なことに、Tがtype1 or type2
であるかどうかをコンパイル時に適用できるものはありません。
また、総称引数がプリミティブ型(int、long、doubleなど)のみであることをコンパイル時に強制する方法もありません。
あなたができるReferenceTypeオブジェクトについて
public void DoIt<T>(T someParameter) where T : IMyType
{
}
...
public interface IMyType
{
}
public class Type1 : IMyType
{
}
public class Type2 : IMyType
{
}
あなたのケースでは、long asパラメータを使用すると、使用法がlongとintに制限されます。
public void DoIt(long someParameter)
{
}
任意の値タイプ(int、double、short、decimalなど)に制約するには、次のように使用できます。
public void DoIt<T>(T someParameter) where T : struct
{
}
詳細については、公式ドキュメントを確認してください ここ
番号。
それは意味がありません。 T
は、メソッドに使用可能なコンパイル時の型がありません。
代わりに、2つのオーバーロードメソッドを作成する必要があります。
代わりにオーバーロードされたメソッドを使用してください:
public void Foo(int number)
{
}
public void Foo(long number)
{
}
とにかくジェネリック型に対して算術演算を実行することはできません。 int
値をlong
パラメータに渡すことができることに注意してください。自動的にlong
に変換されます。したがって、long
パラメータを持つ単一のメソッドがあれば十分です。
古いプログラミング言語は、「1つしか存在できない」という原則に従って機能しました。 C#では、同じクラス、インターフェイス、または構造体に同じ名前の複数のメソッドを含めることができます。これらのメソッドには異なるシグネチャが必要です。つまり、異なる数のパラメーターまたは異なるタイプ(またはその両方)のパラメーターが必要です。これはメソッドのオーバーロードと呼ばれます。
私はこれが古い質問であることを知っており、これは完全に答えるものではありませんが、複数を作成したり、一般的な制約を使用したりするのではなく、単一の方法でこれを行うことができます...チェックする奇数型が20ある場合に特に便利です。
明らかに、制約を使用するときのようにコンパイラー・タイプ・チェックを取得しませんが、これは特定の状況で役立ちます...
public void MyMethod<T>()
{
if (!typeof(T).Equals(typeof(int)) &&
!typeof(T).Equals(typeof(long)))
throw new Exception("T must be int or long");
//your logic here
}
これは現在可能ではないと思います。
この質問 数学ライブラリの作成については、同じことをカバーしており、いくつかの回避策が含まれています。
私にもこの問題があり、より良い解決策を見つけたと思います(メソッドのオーバーロードされたバージョンでは不十分であると想定しています)。
既に記述されているように、Type1
とType2
をパラレルなしで混在させることは意味がありません。したがって、両方のオブジェクトタイプに対してアクセスするメソッドまたはプロパティが必要です。これらのメソッドまたはプロパティがオブジェクトで使用可能であることをコンパイラーに確認するには、インターフェースMyInterface
を作成し、Type1
およびType2
で実装することにより、Type1
およびType2
をグループ化します。
interface MyInterface {
void MyCommonMethod();
bool MyCommonProperty { get; }
}
class Type1 : MyInterface {
void MyCommonMethod() {
// TODO: Implement it for Type1
}
bool MyCommonProperty {
get {
// TODO: Implement it for Type1
}
}
}
class Type2 : MyInterface {
void MyCommonMethod() {
// TODO: Implement it for Type2
}
bool MyCommonProperty {
get {
// TODO: Implement it for Type2
}
}
}
ここで、Foo
メソッドを書き直してType1
とType2
の両方を受け入れるようにして、制約T
をMyInterface
オブジェクトに変更します。
public void Foo<T>(T number) where T : MyInterface
{
throw new NotImplementedException();
}
これは役に立つかもしれないと思います。 :)