こんにちは、私はクラスを持ちたいです:
class Matrix <T>
where T : // I don't know what to write here
{
T[][] elements;
}
T を + 演算子と * 演算子で加算および乗算できるようにしたい
こんにちは、私はクラスを持ちたいです:
class Matrix <T>
where T : // I don't know what to write here
{
T[][] elements;
}
T を + 演算子と * 演算子で加算および乗算できるようにしたい
Messrs SkeetandGravellの「MiscUtil」ライブラリをご覧になることを強くお勧めします。
http://www.yoda.arachsys.com/csharp/miscutil/
中には、信じられないほどの「一般的な数学演算子」の実装が含まれています。これは、一般的な行列数学クラスを作成する試みとうまく一致するはずです。それは実際に私にPythonを(少し)思い出させ、演算子関数を直接参照することをどのように処理するかを思い出させます。
(@ jon-skeetは別として、これがNugetに到達する可能性はありますか?)
彼らのテストからのいくつかの使用例:
double sumOperator = 0;
for (int i = 0; i < COUNT; i++)
{
sumOperator = Operator.Add(sumOperator, rand.NextDouble());
}
int sumOperator = 0;
for (int i = 0; i < COUNT; i++)
{
sumOperator = Operator.Add(sumOperator, rand.Next(MAXVALUE));
}
制約のないジェネリック型は type であると想定されObject
、算術演算子が定義されていないため、これは不可能です。したがって、インターフェイスを指定する必要があるようです。
ただし、プリミティブ型 (Int32、Double など) は算術演算を効果的に静的メソッドとして定義し (実際には、コンパイラはそれらを特別に扱い、コードをインラインで生成します)、C# のインターフェイスは静的メソッドを定義できません (ただし、CLR の設計は実際には許可します)。したがって、算術演算をサポートする要件を満たすインターフェイスを C# で記述することはできません。書けたとしてもプリミティブ型は継承しないので動かない。
その結果、C# でやりたいことを行う方法はありません。
試してみると、次のようなエラーが発生します
Operator '+' cannot be applied to operands of type 'T' and 'T'
このメッセージを Web 検索すると、考えられる回避策に関するさまざまな議論が見つかります。
この方法が誰かの役に立つかもしれません。これを改善するには、fabric-library クラスに加算、乗算関数を配置します。
更新 JerKimball ポストのオペレーターをコンストラクターに配置している可能性があります
class Matrix <T>
{
T[][] elements;
public Matrix(Func<T, T, T> add, Func<T,T,T> multiplicate)
{
this.Add = add;
this.Mult = multiplicate;
}
public Matrix<T> operator +(Matrix<T> p1, Matrix<T> p2)
{
// correct this
var t = Add(p1.elements[0][0], p2.elements[0][0]);
return this;
}
public Matrix<T> operator *(Matrix<T> p1, Matrix<T> p2)
{
// correct this
var t = Mult(p1.elements[0][0], p2.elements[0][0]);
return this;
}
private Func<T, T, T> Add { get; set; }
private Func<T, T, T> Mult { get; set; }
}
static void Main(string[] args)
{
var m1 = new Matrix<int>((x,y) => x + y, (x,y) => x * y);
var m2 = new Matrix<int>((x, y) => x + y, (x, y) => x * y);
}
更新 2
次のようにプロパティへのアクセスを提供するだけです:
public T[][] Elements { get; set; }
そして、あなたはこれを行うことができます:
m1.Elements[0][0] = 10;
var m3 = new Matrix<int?>((x, y) => x + y, (x, y) => x * y);
m3.Elements[0][0] = null;
組み込みのソリューションを知らないので、これをチェックしてください:
public abstract class BaseClass
{
public static BaseClass operator +(BaseClass p1, BaseClass p2)
{
return p1 + p2;
}
public static BaseClass operator *(BaseClass p1, BaseClass p2)
{
return p1 * p2;
}
}
public class ChildClass : BaseClass
{
}
public class Matrix <T> where T : BaseClass
{
T[][] elements;
}
お役に立てれば。
ただし、 などの他のタイプはint
サポートされません。