C#的动态灵活性

时间:2013-03-28 09:37:45

标签: c# dynamic

我最近开始学习编程,并选择.NET和Visual Studio Express。我正在尝试编写一个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());
    }

1 个答案:

答案 0 :(得分:0)

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

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