Out of Memory

本ブログは更新を停止しました。Aerieをよろしくお願いいたします。

目次

Blog 利用状況

ニュース

2009年3月31日
更新を停止しました。引き続きAerieを御愛顧くださいませ。
2009年2月3日
原則としてコメント受付を停止しました。コメントはAerieまでお願いいたします。
詳細は2月3日のエントリをご覧ください。
2008年7月1日
Microsoft MVP for Developer Tools - Visual C++ を再受賞しました。
2008年2月某日
MVPアワードがVisual C++に変更になりました。
2007年10月23日
blogタイトルを変更しました。
2007年7月1日
Microsoft MVP for Windows - SDKを受賞しました!
2007年6月20日
スキル「ニュース欄ハック」を覚えた!
2006年12月14日
記念すべき初エントリ
2006年12月3日
わんくま同盟に加盟しました。

カレンダー

中の人

αετο? / aetos / あえとす

シャノン? 誰それ。

顔写真

埼玉を馬鹿にする奴は俺が許さん。

基本的に知ったかぶり。興味を持った技術に手を出して、ちょっと齧りはするものの、それを応用して何か形にするまでは及ばずに飽きて放り出す人。

書庫

日記カテゴリ

Genericsと暗黙の型変換

まず、前置きとして、以下のようなコードを考えよう。
ごく単純に、コンテナの中の要素のうち、指定された条件を満たすものの数を数えるコードだ。


public static int Count( IEnumerable container, Predicate predicate )
{
    int count = 0;
    foreach( T element in container )
    {
        if( predicate( element ) )
        {
            ++count;
        }
    }
    
    return count;
}

このように使う。結果は予想がつくと思う。

class X
{
    private readonly int _value;
    
    public X( int value )
    {
        _value = value;
    }
    
    public int Value
    {
        get
        {
            return _value;
        }
    }
}
public static bool GreaterThan100( X x )
{
    return ( x.Value > 100 );
}
void Main()
{
    List xs = new List( 10 );
    Random random = new Random();
    
    for( int i = 0; i < 10; ++i )
    {
        int value = random.Next( 150 );
        Console.WriteLine( "new X( {0} )", value );
        
        xs.Add( new X( value ) );
    }
    
    int count = Count( xs, GreaterThan100 );
    Console.WriteLine( count );
}

さて、次のようなクラスを考えたらどうだろうか?

class Y
{
    private readonly X _x;
    
    public Y( int value )
    {
        _x = new X( value );
    }
    
    public static implicit operator X( Y y )
    {
        return y._x;
    }
}

YはXに暗黙の型変換が可能だ。YのインスタンスをGreaterThan100に渡すのは問題ない。
こいつを先程のCount関数で扱えるだろうか?

コードを以下のように書き換える。

void Main()
{
    List ys = new List( 10 );
    Random random = new Random();
    
    for( int i = 0; i < 10; ++i )
    {
        int value = random.Next( 150 );
        Console.WriteLine( "new Y( {0} )", value );
        
        ys.Add( new Y( value ) );
    }
    
    int count = Count( ys, GreaterThan100 );
    Console.WriteLine( count );
}

結論から言おう。このコードはコンパイルエラーになる。
Countはcontainerとpredicateの型引数が同じであることを要求する。YはXに変換可能であるが、Xと同じではないし、Xの派生クラスでもない。

そこで次に、こんなものを考えた。

interface IConvertible
{
    static implicit operator To( IConvertible from );
}
class Y : IConvertible
{
    private readonly X _x;
    
    public Y( int value )
    {
        _x = new X( value );
    }
    
    public static implicit operator X( Y y )
    {
        return y._x;
    }
}
public static int Count( IEnumerable container, Predicate predicate ) where T : IConvertible
{
    int count = 0;
    foreach( T element in container )
    {
        if( predicate( element ) )
        {
            ++count;
        }
    }
    
    return count;
}

「TはUに暗黙の型変換が可能でなければならない」と指定したつもりだったのだが、これも撃沈した。
考えてみれば、C#では演算子はstaticでなければならない。そして、インターフェイスにはstaticメンバを定義できない。まぁ、できたとしても、実際のクラスで実装することができないが。

仕方がないので、明示的に変換メソッドを用意した。

interface IConvertible
{
    To Convert();
}
class Y : IConvertible
{
    private readonly X _x;
    
    public Y( int value )
    {
        _x = new X( value );
    }
    
    public X Convert()
    {
        return _x;
    }
}
public static int Count( IEnumerable container, Predicate predicate ) where T : IConvertible
{
    int count = 0;
    foreach( T element in container )
    {
        if( predicate( element.Convert() ) )
        {
            ++count;
        }
    }
    
    return count;
}

これなら成功した。

C++の次世代規格で、C++0xというのがある。
その中では「コンセプト」と呼ばれる、テンプレート引数に制限を課す仕組みが検討されている。
詳しくはD&Eを参照して頂きたいが、あの冒頭文で、「assignable」というキーワードが登場していた。
今回の例は、紛れもなく「Y is assignable to X」であるが、C#のGenericsは最後のケース以外受け付けなかった。
ひょっとしたら、assignableでは、自動型変換とテンプレートの型推論が同居できるかと思ったのだが…無理なんだっけ?

投稿日時 : 2006年12月23日 15:30

Feedback

# JDAvGiUiHrkXPzwVw 2011/12/27 19:32 www.buytelescopes.com/

Comrade kill yourself.

# VVIUpGSCSFFXtZc 2011/12/29 20:55 http://www.healthinter.org/health/page/lumigan.php

Yeah? I read and I understand that I do not understand anything what it is about:D

# CGuSBvVLCOpISGYOIC 2012/01/07 9:24 http://www.luckyvitamin.com/m-193-natural-factors

Pleased to read intelligent thoughts in Russian. I`ve been living in England for already 5 years!...

タイトル
名前
Url
コメント