2012-02-06 65 views
3

我有一個基於自定義類的應用程序,而且在試圖根據給定替換標記的類型進行自定義替換時遇到了問題。使用反射的代幣替換

我想要做的事(看下面的代碼)給出了一個特定的字符串,循環通過_tokens對象。對於找到的每個令牌,標識令牌替換中提供的對象的類型,並用用戶對象提供的相同對象的值替換它。

對此的任何幫助或其他方法將不勝感激。

編輯:忘了提及,這給了我一個堆棧溢出錯誤。

private BasicUser BU = new BasicUser(); 
private readonly List<Token> _tokens = new List<Token> 
{ 
    new Token 
    { 
    TokenName = "Lan ID", 
    TokenIdentifier = "<!--LANID-->", 
    TokenReplacement = this.BU.LanID 
    }, 
    new Token 
    { 
    TokenName = "First Name", 
    TokenIdentifier = "<!--FirstName-->", 
    TokenReplacement = new BasicUser().FirstName 
    }, 
    new Token 
    { 
    TokenName = "Last Name", 
    TokenIdentifier = "<!--LastName-->", 
    TokenReplacement = new BasicUser().LastName 
    } 
}; 

public string ReplaceTokens(string Input, string LanID) 
{ 
    string OutputString = ""; 
    BasicUser User = GetParticipantInformation(Input); 
    foreach (var token in _tokens) 
    { 
    token.TokenReplacement.GetType(); 
    OutputString = OutputString.Replace(token.TokenName, "Token replacement"); 
    } 
    return OutputString; 
} 
+0

你知道什麼是溢出?我沒有看到任何遞歸調用或任何會暗示棧溢出的東西。 – deepee1 2012-02-06 20:46:40

+1

看起來你已經省略了一些重要的東西。 'token.TokenReplacement.GetType()'行沒有意義。 'OutputString'將始終爲空...... – 2012-02-06 20:47:58

+2

如果可能的話,您應該提供一個很小的_working_問題示例。 – 2012-02-06 20:48:22

回答

2

是的,你可以使用反射。只需使用PropertyInfo類型TokenReplacement並分配給它的屬性,你需要像下面這樣:

class Token { 
    string TokenName; 
    string TokenIdentifier; 
    PropertyInfo TokenReplacement; 
} 

private readonly List<Token> _tokens = new List<Token> 
{ 
    new Token 
    { 
    TokenName = "Lan ID", 
    TokenIdentifier = "<!--LANID-->", 
    TokenReplacement = typeof(BasicUser).GetProperty("LanID") 
    }, 
    new Token 
    { 
    TokenName = "First Name", 
    TokenIdentifier = "<!--FirstName-->", 
    TokenReplacement = typeof(BasicUser).GetProperty("FirstName") 
    } 
}; 

public string ReplaceTokens(string Input, string LanID) 
{ 
    string OutputString = ""; 
    BasicUser User = GetParticipantInformation(Input); 
    foreach (var token in _tokens) 
    { 
    OutputString = OutputString.Replace(token.TokenName, token.TokenReplacement.GetValue(User, null).ToString()); 
    } 
    return OutputString; 
} 

如果你不需要這是基於反射,你也可以去馬蒂Virkkunen的方式,允許指定一些比簡單屬性讀取更復雜的對象查詢。

+0

謝謝!這正是我需要的。 – 2012-02-06 21:33:44

2

我想修改這段代碼做你想要的東西會修改令牌的最簡單的方法中包含的,而不是...無論TokenReplacement目前是對象或函數。

class Token { 
    Func<BasicUser, object> TokenReplacement; 
    // ... 
} 

// ... 

    new Token 
    { 
    TokenName = "Lan ID", 
    TokenIdentifier = "<!--LANID-->", 
    TokenReplacement = user => user.LanID, 
    }, 
    new Token 
    { 
    TokenName = "First Name", 
    TokenIdentifier = "<!--FirstName-->", 
    TokenReplacement = user => user.FirstName, 
    }, 

// ... 

OutputString = OutputString.Replace(token.TokenName, 
    token.TokenReplacement(User).ToString()); 

另一種方法是完全失去了_tokens列表,而是建立值的字典,然後取代一切,看起來像從字典中的值的標籤。使用正則表達式很容易找到看起來像標籤的東西。

+0

好的解決方案。我假設他真的需要token.TokenIdentifier作爲Replace的第一個參數,但他的例子留下了很多不明確之處。 – deepee1 2012-02-06 20:50:57

+0

@ deepee1:可能。我只是複製粘貼。 – 2012-02-06 20:51:37

+1

偉大的解決方案,但OP是要求基於反射的解決方案。但如果這不是要求,我喜歡這個,並且會一樣。 – Krizz 2012-02-06 21:08:25