【问题标题】:Token Replacement Using Reflection使用反射替换令牌
【发布时间】:2012-02-06 20:39:13
【问题描述】:

我有一个相当多地基于自定义类的应用程序,并且在尝试根据给定替换令牌的类型进行自定义替换时遇到了困难。

我想要做的(看下面的代码)给定一个特定的字符串,循环遍历 _tokens 对象。对于找到的每个令牌,确定 TokenReplacement 中提供的对象类型,并将其替换为 User 对象提供的同一对象的值。

对此的任何帮助或其他方法将不胜感激。

编辑:忘了说这会给我一个堆栈溢出错误。

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;
}

【问题讨论】:

  • 你知道溢出的是什么吗?我没有看到任何递归调用或任何其他暗示堆栈溢出的内容。
  • 您似乎遗漏了一些重要的内容。 token.TokenReplacement.GetType() 行没有意义。 OutputString 将永远为空...
  • 如果可能的话,您应该提供一个小的工作示例。
  • 我错过了什么吗?这如何涉及反射?

标签: c# reflection token replace


【解决方案1】:

是的,您可以使用反射。只需使用 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;
}

如果您不需要基于反射,您也可以采用 Matti Virkkunen 的方式,它允许在对象上指定一些比简单属性读取更复杂的查询。

【讨论】:

  • 谢谢!这正是我所需要的。
【解决方案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 列表,而是构建一个值字典,然后用字典中的值替换所有看起来像标签的东西。使用正则表达式可以轻松找到看起来像标签的东西。

【讨论】:

  • 很好的解决方案。我假设他真的希望 token.TokenIdentifier 作为 Replace 的第一个参数,但他的示例留下了很多歧义。
  • @deepee1:可能。我只是复制粘贴的。
  • 很好的解决方案,但 OP 要求基于反射的解决方案。但如果这不是必需的,我喜欢这个,并且会这样做。
  • @Krizz:我通常会忽略这样的任意约束并尝试专注于问题,而不是当前的无效解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-07
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多