2

以下のコードで、myLine をパブリック (グローバル) 変数として宣言するにはどうすればよいですか? 問題は、キーワード「var」を使用できないことです。

    public static IEnumerable<string> ReadLines(StreamReader reader)
    {
        while (!reader.EndOfStream)
        {
            yield return reader.ReadLine();
        }
    }

    private void Filter1(string filename)
    {
        using(var writer = File.CreateText(Application.StartupPath + "\\temp\\test.txt"))
        {
            using (var reader = File.OpenText(filename))
            {
                int[] Ids = { 14652, 14653, 14654, 14655, 14656, 14657, 14658, 14659, 14660 };
                var myLine = from line in ReadLines(reader)
                             where line.Length > 1
                             let id = int.Parse(line.Split('\t')[1])
                             where Ids.Contains(id)
                             let m = Regex.Match(line, @"^\d+\t(\d+)\t.+?\t(item\\[^\t]+\.ddj)")
                             where m.Success == true
                             select new { Text = line, ItemId = id, Path = m.Groups[2].Value };


                foreach (var id in myLine)
                {
                    writer.WriteLine("Item Id = " + id.ItemId);
                    writer.WriteLine("Path = " + id.Path);
                    writer.WriteLine("\n");
                }

            }
        }
    }

後で使用するためにその列挙型にアクセスする方法を見つけなければならないので、私はそれをやりたいです。

4

2 に答える 2

8

問題は、フィールド宣言で使用できない匿名型を使用していることです。

修正は、同じメンバーを持つ名前付きの型を記述し、その型をクエリで使用することです。匿名型と同じ動作をさせたい場合は、次のようにする必要があります。

  • コンストラクターですべての値を取得する
  • 不変であり、読み取り専用プロパティを公開する
  • をオーバーライドしEqualsGetHashCodeToString
  • 封印される

Reflector を使用してコードを逆コンパイルすることもできますが、実際には必要のないジェネリック型になってしまいます。

クラスは次のようになります。

public sealed class Foo
{
    private readonly string text;
    private readonly int itemId;
    private readonly string path;

    public Foo(string text, int itemId, string path)
    {
        this.text = text;
        this.itemId = itemId;
        this.path = path;
    }

    public string Text
    {
        get { return text; }
    }

    public int ItemId
    {
        get { return itemId; }
    }

    public string Path
    {
        get { return path; }
    }

    public override bool Equals(object other)
    {
        Foo otherFoo = other as Foo;
        if (otherFoo == null)
        {
            return false;
        }
        return EqualityComparer<string>.Default.Equals(text, otherFoo.text) &&
        return EqualityComparer<int>.Default.Equals(itemId, otherFoo.itemId) &&
        return EqualityComparer<string>.Default.Equals(path, otherFoo.path);
    }

    public override string ToString()
    {
        return string.Format("{{ Text={0}, ItemId={1}, Path={2} }}",
                             text, itemId, path);
    }

    public override int GetHashCode()
    {
        int hash = 17;
        hash = hash * 23 + EqualityComparer<string>.Default.GetHashCode(text);
        hash = hash * 23 + EqualityComparer<int>.Default.GetHashCode(itemId);
        hash = hash * 23 + EqualityComparer<string>.Default.GetHashCode(path);
        return hash;
    }
}

クエリは最後に次のように変更されます。

select new Foo(line, id, m.Groups[2].Value)
于 2009-06-08T10:57:00.793 に答える
2

新しいキーボードで匿名クラスを使用する代わりに、Text、ItemId などを使用してクラスを明示的に定義します。その場合、型は IQueryable<MyClass> になります。varキーワードの代わりにそれを使用します。

于 2009-06-08T10:59:05.393 に答える