C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.17818 の関連記事表示

<< 0 >>
■17818  C#のジェネリックの制約について
□投稿者/ studyC# -(2008/05/02(Fri) 09:10:59)

    分類:[C#] 

    こんにちわ。初めて投稿します。
    現在、C#(3.0)を勉強中です。よろしくお願いいたします。

    C#のジェネリックについて質問があります。

    例えば、次のような足し算や引き算を含むコードがあります。

    class MyMath
    {
    public MyMath()
    {

    }

    public int add(int x, int y)
    {
    return x + y;
    }

    public int minus(int x, int y)
    {
    return x - y;
    }
    }

    このコードだと、doubleの足し算や引き算をしたい場合には、add()やminus()をオーバーロードしなくてはいけなくなり面倒です。

    そこで、ジェネリックを使い、

    class MyMath<T>
    {
    public MyMath()
    {

    }

    public T add(T x, T y)
    {
    return x + y;
    }

    public T minus(T x, T y)
    {
    return x - y;
    }
    }

    とすれば、うまくいくかと思いきや、T型は+や-ができるかわからないとコンパイラにはじかれました。
    当然のことなのですが。。。

    そこでwhereでTに対して+や-の演算ができるように制約をつけようと思っているのですが、制約に何を指定すればいいか探してみたのですがわかりませんでした。
    そもそも、こういうことはできないのでしょうか><

    わかる方がいらっしゃいましたら、ご助言いただけるとありがたいです。
    すみませんが、よろしくお願いいたします。
親記事 /過去ログ35より / 関連記事表示
削除チェック/

■17822  Re[1]: C#のジェネリックの制約について
□投稿者/ 魔界の仮面弁士 -(2008/05/02(Fri) 09:28:54)
    No17818 (studyC# さん) に返信
    > 例えば、次のような足し算や引き算を含むコードがあります。
    static で良いのでは無いか、という突っ込みはさておき。
    
    > そこでwhereでTに対して+や-の演算ができるように制約をつけようと思っているのですが、
    > 制約に何を指定すればいいか探してみたのですがわかりませんでした。
    3.0 でどうなっているかは把握していませんが、2.0 においては
    制約等では対処できなかったように思います。
    
    > そもそも、こういうことはできないのでしょうか><
    2.0 の時は、こんな方法で逃げていました。
    
    static class MyMath<T>
    {
        public static T Add(T x, T y)
        {
            return (T)Microsoft.VisualBasic.CompilerServices.Operators.AddObject(x, y);
        }
    
        public static T minus(T x, T y)
        {
            return (T)Microsoft.VisualBasic.CompilerServices.Operators.SubtractObject(x, y);
        }
    }
記事No.17818 のレス /過去ログ35より / 関連記事表示
削除チェック/

■17865  Re[2]: C#のジェネリックの制約について
□投稿者/ studyC# -(2008/05/02(Fri) 16:47:44)
    No17822 (魔界の仮面弁士 さん) に返信

    回答ありがとうございます。

    > static で良いのでは無いか、という突っ込みはさておき。

    そうですね。このケースだとstaticですね^^
    突っ込みありがとうございます。

    > 2.0 の時は、こんな方法で逃げていました。

    制約では対処できないのですねぇ。
    なんかやり方がある筈と思ってましたが・・・orz

    Microsoft.VisualBasic.CompilerServices.Operators.AddObjectなんてものがあるのですね。
    勉強になりました。
    親切な回答ありがとうございましたm(_ _)m

    > ■No17818 (studyC# さん) に返信
    >>例えば、次のような足し算や引き算を含むコードがあります。
    > static で良いのでは無いか、という突っ込みはさておき。
    >
    >>そこでwhereでTに対して+や-の演算ができるように制約をつけようと思っているのですが、
    >>制約に何を指定すればいいか探してみたのですがわかりませんでした。
    > 3.0 でどうなっているかは把握していませんが、2.0 においては
    > 制約等では対処できなかったように思います。
    >
    >>そもそも、こういうことはできないのでしょうか><
    > 2.0 の時は、こんな方法で逃げていました。
    >
    > static class MyMath<T>
    > {
    > public static T Add(T x, T y)
    > {
    > return (T)Microsoft.VisualBasic.CompilerServices.Operators.AddObject(x, y);
    > }
    >
    > public static T minus(T x, T y)
    > {
    > return (T)Microsoft.VisualBasic.CompilerServices.Operators.SubtractObject(x, y);
    > }
    > }
記事No.17818 のレス / END /過去ログ35より / 関連記事表示
削除チェック/

■17870  Re[3]: C#のジェネリックの制約について
□投稿者/ 魔界の仮面弁士 -(2008/05/02(Fri) 18:04:52)
    2008/05/02(Fri) 22:13:02 編集(投稿者)

    # 解決チェックを外してしまっていたので、つけなおし。

    No17865 (studyC# さん) に返信
    VB だったら、Option Strict Off にしておいて、
     Return CObj(a) + CObj(b)
    とする手もあるのですけれどね。


    > そうですね。このケースだとstaticですね^^
    と思いましたが、型パラメータの指定を考えると、インスタンスメソッドの方が楽かも…。

    同じ演算子を繰り返し使う場合、型引数を毎回指定して
     a = MyMath<System.Int32>.Minus(30, 12);
     b = MyMath<System.Int32>.Minus(30, 10);
    と書かせるよりも、
     a = foo.Minus(30, 12);
     b = foo.Minus(30, 10);
    のように書けた方が楽ですし。


    もし、static にするのであれば、
    static class MyMath<T>
    {
    public static T Minus(T x, T y) { … }
    }
    ではなく、
    static class MyMath
    {
    public static T Minus<T>(T x, T y) { … }
    }
    とするのも手かも知れません。これなら利用時は、
     int c = MyMath.Minus(30, 8);
    のように、型推論が使えますので。


    >>2.0 の時は、こんな方法で逃げていました。
    > 制約では対処できないのですねぇ。
    > なんかやり方がある筈と思ってましたが・・・orz
    C# は専門外なので、単に私が知らないだけかも知れませんけれどね。


    > Microsoft.VisualBasic.CompilerServices.Operators.AddObjectなんてものがあるのですね。
    他に使えそうなのは、Microsoft.JScript.Plus.DoOp とか、IL の動的生成とか。


    演算効率を落としても良ければ、こんな手も。

    public class MyMath<T>
    {
    DataRow row;
    public MyMath()
    {
    DataTable dt = new DataTable();
    dt.Columns.Add("x", typeof(T));
    dt.Columns.Add("y", typeof(T));
    dt.Columns.Add("Plus", typeof(T)).Expression = "x+y";
    dt.Columns.Add("Minus", typeof(T)).Expression = "x-y";
    row = dt.Rows.Add();
    }

    private T DoOp(T x, T y, string method)
    {
    row["x"] = x;
    row["y"] = y;
    return (T)row[method];
    }

    public T Plus(T x, T y) { return DoOp(x, y, "Plus"); }
    public T Minus(T x, T y) { return DoOp(x, y, "Minus"); }
    }
記事No.17818 のレス / END /過去ログ35より / 関連記事表示
削除チェック/

■17911  Re[4]: C#のジェネリックの制約について
□投稿者/ studyC# -(2008/05/03(Sat) 15:07:37)
    No17870 (魔界の仮面弁士 さん) に返信

    魔界の仮面弁士さん、またまた回答ありがとうございますm(_ _)m

    >  a = MyMath<System.Int32>.Minus(30, 12);
    >  b = MyMath<System.Int32>.Minus(30, 10);
    > と書かせるよりも、
    >  a = foo.Minus(30, 12);
    >  b = foo.Minus(30, 10);
    > のように書けた方が楽ですし。

    なるほど。
    確かにそうですね。

    > static class MyMath
    > {
    > public static T Minus<T>(T x, T y) { … }
    > }
    > とするのも手かも知れません。これなら利用時は、
    >  int c = MyMath.Minus(30, 8);
    > のように、型推論が使えますので。

    おぉぉ、型推論ですか!
    確かに、これだと引数からTが推測できるので<>の指定がいらなくなるわけですね@@
    勉強になります。ありがとうございます。

    > C# は専門外なので、単に私が知らないだけかも知れませんけれどね。

    えぇ><
    これで専門外なのですが。。。
    私ももっと精進しないと!!

    ありがとうございました。

    > 2008/05/02(Fri) 22:13:02 編集(投稿者)
    >
    > # 解決チェックを外してしまっていたので、つけなおし。
    >
    > ■No17865 (studyC# さん) に返信
    > VB だったら、Option Strict Off にしておいて、
    >  Return CObj(a) + CObj(b)
    > とする手もあるのですけれどね。
    >
    >
    >>そうですね。このケースだとstaticですね^^
    > と思いましたが、型パラメータの指定を考えると、インスタンスメソッドの方が楽かも…。
    >
    > 同じ演算子を繰り返し使う場合、型引数を毎回指定して
    >  a = MyMath<System.Int32>.Minus(30, 12);
    >  b = MyMath<System.Int32>.Minus(30, 10);
    > と書かせるよりも、
    >  a = foo.Minus(30, 12);
    >  b = foo.Minus(30, 10);
    > のように書けた方が楽ですし。
    >
    >
    > もし、static にするのであれば、
    > static class MyMath<T>
    > {
    > public static T Minus(T x, T y) { … }
    > }
    > ではなく、
    > static class MyMath
    > {
    > public static T Minus<T>(T x, T y) { … }
    > }
    > とするのも手かも知れません。これなら利用時は、
    >  int c = MyMath.Minus(30, 8);
    > のように、型推論が使えますので。
    >
    >
    > >>2.0 の時は、こんな方法で逃げていました。
    >>制約では対処できないのですねぇ。
    >>なんかやり方がある筈と思ってましたが・・・orz
    > C# は専門外なので、単に私が知らないだけかも知れませんけれどね。
    >
    >
    >>Microsoft.VisualBasic.CompilerServices.Operators.AddObjectなんてものがあるのですね。
    > 他に使えそうなのは、Microsoft.JScript.Plus.DoOp とか、IL の動的生成とか。
    >
    >
    > 演算効率を落としても良ければ、こんな手も。
    >
    > public class MyMath<T>
    > {
    > DataRow row;
    > public MyMath()
    > {
    > DataTable dt = new DataTable();
    > dt.Columns.Add("x", typeof(T));
    > dt.Columns.Add("y", typeof(T));
    > dt.Columns.Add("Plus", typeof(T)).Expression = "x+y";
    > dt.Columns.Add("Minus", typeof(T)).Expression = "x-y";
    > row = dt.Rows.Add();
    > }
    >
    > private T DoOp(T x, T y, string method)
    > {
    > row["x"] = x;
    > row["y"] = y;
    > return (T)row[method];
    > }
    >
    > public T Plus(T x, T y) { return DoOp(x, y, "Plus"); }
    > public T Minus(T x, T y) { return DoOp(x, y, "Minus"); }
    > }
記事No.17818 のレス / END /過去ログ35より / 関連記事表示
削除チェック/

■17820  Re[1]: C#のジェネリックの制約について
□投稿者/ Jitta -(2008/05/02(Fri) 09:23:47)
>
    2008/05/02(Fri) 09:24:51 編集(投稿者)

    No17818 (studyC# さん) に返信
    operator +
    とかじゃないかな?

    ちげ。。。質問の意味間違えた。無視してください。
記事No.17818 のレス /過去ログ35より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -