1

我最近开始学习编程并选择了带有 Visual Studio Express 的 .NET。我正在尝试编写一个 CSV 解析器作为一种学习体验,它给我带来的麻烦比我预期的要多得多。我从读者开始。我在解析器中做的不同的一件事是我没有使用引号。我用反斜杠转义逗号,用反斜杠转义反斜杠,用反斜杠转义换行符。例如,如果逗号前面有偶数个反斜杠,则它是一个字段,我将任何反斜杠块减半。如果它很奇怪,它不是字段结束,我仍然将反斜杠块减半。我不确定如果我能让它工作起来会有多强大,除了我现在只是在学习,而且我主要把它看作是操作数据结构的练习。

我有一个关于这篇文章底部的代码片段的问题,以及如何使它不那么静态和限制,并且仍然为我编译和运行。

代码行如下:

var contents = (String)fileContents;

我一直在努力使其更具动态性以增加灵活性并使其变得像这样:

var contents = (otherVariableThatCouldChangeTypeAtRuntime.GetType())fileContents;

我可以做些什么来让它这样做并且仍然编译吗?也许像 VB.NET 中的 Option Infer 这样的东西可能会有所帮助,但我找不到。

另外,我也在 VB.NET 中编写了这个。在我看来,VB.NET 允许我使用比我在下面发布的更动态的样式,例如不必一遍又一遍地键入 var 并且不必一遍又一遍地将我的索引计数变量转换为整数如果我关闭 Option Strict 和 Option Explicit 并打开 Option Infer,则再次。例如,C# 不允许我键入类似于以下 VB.NET 代码的内容,即使我知道我将在运行时调用的方法和属性将在运行时存在。

    Dim contents As Object = returnObjectICantDetermineAtComplieTime()
    contents.MethodIKnowWillBeThereAtRunTime()

我可以在 C# 中做这些事情吗?无论如何,这是代码,并提前感谢您的任何回复。

    public class Widget
    {
        public object ID { get; set; }
        public object PartNumber { get; set; }
        public object VendorID { get; set; }
        public object TypeID { get; set; }
        public object KeyMarkLoc { get; set; }

        public Widget() { }
    }

    public object ReadFromFile(object source)
        {
            var fileContents = new FileService().GetFileContents(source);
            object records = null;

            if (fileContents == null)
                return null;

            var stringBuffer = "";
            var contents = (String)fileContents;

            while (contents.Length > 0 && contents != "\r\n")
            {
                for (object i = 0; (int)i < contents.Length; i=(int)i+1 )
                {
                    object character = contents[(int)i];

                    if (!stringBuffer.EndsWith("\r\n"))
                    {
                        stringBuffer += character.ToString();
                    }

                    if (stringBuffer.EndsWith("\r\n"))
                    {
                        var bSlashes = getBackSlashes(stringBuffer.Substring(0, stringBuffer.Length - 4));
                        stringBuffer = stringBuffer.Substring(0, stringBuffer.Length - 4);
                        if ((int)bSlashes % 2 == 0)
                        {
                            break;
                        }
                    }
                }

                contents = contents.Substring(stringBuffer.Length+2);
                records = records == null ? getIncrementedList(new List<object>(), getNextObject(getFields(stringBuffer))) : getIncrementedList((List<object>)records, getNextObject(getFields(stringBuffer)));
            }

            return records;
        }

        private Widget getNextRecord(object[] fields)
        {
            var personStudent = new Widget();

            personStudent.ID = fields[0];
            personStudent.PartNumber = fields[1];
            personStudent.VendorID = fields[2];
            personStudent.TypeID = fields[3];
            personStudent.GridPath = fields[4];

            return personStudent;
        }

        private object[] getFields(object buffer)
        {
            var fields = new object[5];
            var intFieldCount = 0;
            var fieldVal = "";
            var blocks = buffer.ToString().Split(',');
            foreach (var block in blocks) 
            {
                var bSlashes = getBackSlashes(block);

                var intRemoveCount = (int)bSlashes / 2;
                if ((int)bSlashes % 2 == 0) // Delimiter
                {
                    fieldVal += block.Substring(0, block.Length - intRemoveCount);
                    fields[intFieldCount] += fieldVal;
                    intFieldCount++;
                    fieldVal = "";
                }
                else // Part of Field
                {
                    fieldVal += block.Substring(0, block.Length - intRemoveCount - 1) + ",";
                }
            }

            return fields;
        }

        private object getBackSlashes(object block)
        {
            object bSlashes = block.ToString().Length == 0 ? new int?(0) : null;
            for (object i = block.ToString().Length - 1; (int)i>-1; i=(int)i-1)
            {
                if (block.ToString()[(int)i] != '\\') return bSlashes = bSlashes == null ? 0 : bSlashes;
                bSlashes = bSlashes == null ? 1 : (int)bSlashes + 1;
            }

            return bSlashes;
        }
    }

这是网络服务代码。

    [WebMethod]
    public object GetFileContents(object source)
    {
        return File.ReadAllText(source.ToString());
    }
4

1 回答 1

0
Dim contents As Object = returnObjectICantDetermineAtComplieTime()
contents.MethodIKnowWillBeThereAtRunTime()

您可以使用dynamic类型执行此操作。有关详细信息,请参阅:http: //msdn.microsoft.com/en-us/library/dd264736.aspx

于 2013-03-28T09:40:05.090 回答