0

私は何度も何度も私の特定の方法を使用しています。したがって、このクラスをすべてのプロジェクトにインポートする傾向があります。このプロジェクトでは、WindowsPhoneデバイスのIsolatedStorageにアクセスする必要があります。

しかし、それは私には本当にエレガントに見えません。見てください:

public static Object getFileContent (String filename, String returntype)
        {
            IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

            Object returnobj = new Object();
            List<String> list = new List<String>();
            String r;

            IsolatedStorageFileStream fileStream = isf.OpenFile(filename, FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(fileStream);

            if (returntype.Equals("list"))
            {
                while ((r = reader.ReadLine()) != null)
                {
                    list.Add(r);
                }
                returnobj = list;
            }
            else if (returntype.Equals("string"))
            {
                r = reader.ReadLine();
                returnobj = r;
            }

            fileStream.Close();
            reader.Close();

            return returnobj;
        }

私の主な問題はパラメータreturntypeです。明らかに文字列です。直接型として欲しいのですが。しかし、それは私の最後の試みではうまくいきませんでした。

また、この方法を使用すると、たとえば次のようになります。

string random = (string) MyFavClass.getFileContent("randomFile","string");

使用する前に、そのメソッドの戻り型をもう一度変換する必要があります。

4

4 に答える 4

5

2つのメソッドを書くだけです:getFileContentAsStringgetFileContentAsList。正確に2つのタイプしかサポートできない場合、ここでは汎用性のメリットは得られません。

于 2013-03-19T16:41:28.037 に答える
1

任意の数のリターンタイプを使用する場合は、ストラテジーパターンを使用できます。

public static T GetFileContents<T>(String filename, Func<StreamReader, T> readMethod)
{
    // initialize stuff

    using (StreamReader reader = new StreamReader(...))
    {
        return readMethod(reader);
    }
}

public static string ReadStreamAsString(StreamReader reader)
{
    return reader.ReadLine();
}

public static List<string> ReadStreamAsList(StreamReader reader)
{
    var list = new List<string>();

    while ((r = reader.ReadLine()) != null)
    {
        list.Add(r);
    }

    return list;
}

そしてそれを使用するには:

string myString = GetFileContents("foo.txt", ReadStreamAsString);

List<string> myList = GetFileContents("bar.xml", ReadStreamAsList);

私のジェネリックはおそらくオフですが、うまくいけばそれは正しい考えを伝えます。

于 2013-03-19T16:47:27.960 に答える
0

テストされていませんが、私は次のようなことをしようとします:

public static T getFileContent (String filename, Func<StreamReader, T> process)
    {
        IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

        Object returnobj = new Object();
        List<String> list = new List<String>();
        String r;

        IsolatedStorageFileStream fileStream = isf.OpenFile(filename, FileMode.Open, FileAccess.Read);
        StreamReader reader = new StreamReader(fileStream);

        try{
            return process(reader);
        }
        finally{
            fileStream.Close();
            reader.Close();
        }
    }

私が持っているので、これはエラーが発生しやすいと確信していますが、アイデアは、返したいタイプを処理するコンバーター関数を渡すことです。

于 2013-03-19T16:46:16.773 に答える
0

仮定:

  1. リストに必要なのは、読み取り専用、転送専用のアクセスだけです。と
  2. 両方の可能性の結果をアプリケーションコードで同じように扱うことが望まれます。

それから彼は次のように働くでしょう:

  public abstract class MySequence : IEnumerable<string> {
    protected string Filename { get; private set; }

    public MySequence(string filename) {
      Filename = filename;
    }

    IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }

    public IEnumerator<string> GetEnumerator() {
      using (var isf = IsolatedStorageFile.GetUserStoreForApplication()) 
      using (var stream = isf.OpenFile(Filename, FileMode.Open, FileAccess.Read))
      using (var reader = new StreamReader(stream)) {
        return GetEnumerator(reader);
      }
    }
    protected abstract IEnumerator<string> GetEnumerator(StreamReader reader);
  }
  public class MyListSequence : MySequence, IEnumerable<string> {
    public MyListSequence(string filename) : base(filename) {}
    protected override IEnumerator<string> GetEnumerator(StreamReader reader) {
      while (! reader.EndOfStream) yield return reader.ReadLine();
    }
  }
  public class MyStringSequence : MySequence, IEnumerable<string> {
    public MyStringSequence(string filename) : base(filename) {}
    protected override IEnumerator<string> GetEnumerator(StreamReader reader) {
      yield return reader.ReadLine();
    }
  }

使用法は次のようになります。

  foreach (var s in (new MyListSequence("fred"))) { Console.WriteLine(s); }
  foreach (var s in (new MyStringSequence("fred"))) { Console.WriteLine(s); }

このメカニズムの特別な利点は、tiが適用される場合、リストにストレージを割り当てる必要がないことです。eaxhテキスト行は、イテレータによって読み取られて返されます。

于 2013-03-19T17:57:41.290 に答える