0

我一遍又一遍地使用我的某种方法。因此,我倾向于将这个类导入到我的所有项目中,在那里我必须访问 Windows Phone 设备的独立存储。

但是,它对我来说似乎并不优雅。看一看:

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

只需编写两个方法:getFileContentAsStringgetFileContentAsList. 如果您只能支持两种类型,那么您不会在这里获得任何通用性的好处。

于 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

假设:

  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 回答
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 回答