- PR -

C# TextReaderの継承について

1
投稿者投稿内容
たち吉
会議室デビュー日: 2006/08/01
投稿数: 8
投稿日時: 2006-08-01 21:31
はじめて投稿させていただきます。

例えば StreamReader クラスなのですが、どのようにして
ReadBlock メソッドを実装しているのでしょうか。

質問の趣旨は、

public int ReadBlock (
  [InAttribute] [OutAttribute] char[] buffer,
  int index,
  int count
)

で渡される buffer を、ref を使わずにどうやって内容を
書き換えているのか、です。

TextReader を継承するクラスを実装しており、方向属性を
気にしてソースに InAttribute、OutAttributeを付けてみたのですが、
引数のbufferを書き換えることができません。

この辺にお詳しい方、どうぞご教示願います。
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-08-01 21:55
んん?
普通に書き込めばいいだけのはずですが?

コード:
public static void Write(char[] chars) {
    for (int i = 0; i < chars.Length; i++) {
        chars[i] = (char)(40+i);
    }
}
public static void Main() {
    char[] chars = new char[32];
    Write(chars);
    foreach (char c in chars) {
        Console.Write(c);
    }
}



ちなみに、In/Out は .NET で動かす分には基本的に関係ないです。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-08-01 21:59
引用:

OutAttribute はオプションです。この属性は、COM 相互運用、およびプラットフォーム呼び出しのときにだけ使用できます。明示的な設定がない場合、相互運用マーシャラは、パラメータの型 (パラメータが参照渡しか値渡しか、型が blittable か非 blittable か) に応じて規則を判断します。たとえば、StringBuilder クラスは常に In/Out として扱われ、値渡しされた文字列の配列は In として扱われます。

Out のみの動作がパラメータの既定のマーシャリング動作となることはありません。参照渡しの値型または参照型に OutAttribute を適用することによって、In/Out の動作を Out のみの動作に変更できます。これは、C# で out キーワードを使用することに相当します。たとえば、値渡しの配列 (既定で In のみのパラメータとしてマーシャリングされる) は、Out のみに変更できます。ただし、相互運用マーシャラは固定を使用するため、要素またはフィールドがすべて blittable の型の場合、この動作は期待されるセマンティクスを提供しないことがあります。データを呼び出し先に渡すかどうかが問題にならない場合、非 blittable 型については Out のみのマーシャリングの方がパフォーマンスに優れています。

InAttribute と OutAttribute を組み合わせると、配列型および書式付きの非 blittable 型に適用する場合に、特に役立ちます。両方の属性を適用した場合にのみ、呼び出し元は、呼び出し先がこれらの型に対して加えた変更を参照できます。これらの型はマーシャリング中にコピーを要求するため、InAttribute と OutAttribute を使用して、不要なコピーを減らすことができます。

マーシャリングの動作に OutAttribute が与える影響の詳細については、「方向属性」を参照してください。

たち吉
会議室デビュー日: 2006/08/01
投稿数: 8
投稿日時: 2006-08-01 23:04
Hongliangさん、Jittaありがとうございます。

Hongliangさんの書かれたコードからヒントを得て、配列の各要素を
一つひとつ代入することで解決できました。

以下、解説です。

コード:
public override int ReadBlock(char[] buffer, int index, int count)
{
    // MyMethodは、Char[]を返すメソッド
    buffer = MyMethod(index, count);

    // Debug用
    Console.WriteLine(buffer, index, count);

    return buffer.Length;
}


はじめは上記のようにbufferに直接代入しており、メソッド内では
コンソールに問題なく出力できていたため、問題に気付けませんでした。
ありがとうございます。



1

スキルアップ/キャリアアップ(JOB@IT)