我最近開始學習編程,並使用Visual Studio Express選擇了.NET。我正在嘗試寫一個CSV解析器作爲一種學習體驗,它給我帶來了比我想象的更多的麻煩。我從讀者開始。我在解析器中做的不同之處在於我沒有使用引號。我使用反斜槓,帶反斜槓的反斜槓和帶反斜線的換行符來轉義逗號。例如,如果逗號之前是偶數個反斜槓,則它是一個字段,並將任意反斜槓塊減半。如果它很奇怪,那不是場地末端,我仍然減半反斜槓。我不確定如果我能夠實現它的工作,這將會是多麼強大,除了我現在只是在學習,我主要將它看作是操縱數據結構的練習。C#中的動態靈活性
我有一個問題,引用這篇文章底部的代碼片段,以及如何使它不那麼靜態和限制,仍然編譯和爲我運行。
的代碼行,上面寫着:
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;
}
}
這是Web服務代碼。
[WebMethod]
public object GetFileContents(object source)
{
return File.ReadAllText(source.ToString());
}