【发布时间】:2015-04-05 21:22:22
【问题描述】:
如何避免属性 getter 中的递归调用?这是我的简单代码
public class UploadAttribute : Attribute
{
private Type _resourceType;
private string _select;
private string _change;
private string _remove;
public Type ResourceType
{
get { return _resourceType; }
set { _resourceType = value; }
}
public string Select
{
get { return GetResourceText(m => m.Select, "Select..."); }
set { _select = value; }
}
public string Change
{
get { return GetResourceText(m => m.Change, "Change..."); }
set { _change = value; }
}
public string Remove
{
get { return GetResourceText(m => m.Remove, "Remove"); }
set { _remove = value; }
}
private string GetResourceText(Expression<Func<UploadAttribute, string>> expression, string @default)
{
var value = expression.Compile().Invoke(this); // here .net is creating new UploadAttribute instance and use it for expression fnc
var result = value ?? @default;
if (_resourceType != null && !string.IsNullOrEmpty(value))
{
ResourceManager rm = new ResourceManager(_resourceType);
try
{
result = rm.GetString(value);
}
catch
{
// if string wasn't found in resource file than use what user specify; don't by big brother.
}
}
return result;
}
}
但是,如果您查看 GetResourceText 方法,我需要在其中编译和调用表达式以获取给定属性的值。不幸的是,此操作创建了 UploadAttribute 的新实例。在那一刻,.net 遍历所有属性并调用 getter,如果我没记错的话,在 getter 中,.net 编译并调用表达式以获取值或给定属性,一次又一次地返回 StackOverlowException。 你能建议我如何避免这种行为,但这个解决方案很简单吗?
编辑: 此类的目的是为按钮提供标题 - 用户设置的内容可以使用资源管理器中的多语言标题。 在上面的示例中,按钮选择从资源翻译,更改按钮使用默认文本“更改...”,删除按钮标题“销毁此@!”。因此,如果用户没有指定属性值,应用程序使用默认文本,否则尝试在资源中查找文本,如果找到匹配项,则使用资源中的文本,否则使用用户设置的内容。
[Required]
[Upload(ResourceType = typeof(Resource), Select = "UploadSelect", Remove = "Destroy this @&#!")]
public HttpPostedFileBase Logo { get; set; }
【问题讨论】:
-
您似乎将 attributes 属性值设置为两种不同类型的值:(1) 用于从资源中检索标题字符串的资源键,(2) 文字用作标题本身的字符串。这绝对不是一个干净的方法,虽然我自己永远不会选择这样的脆弱设计解决方案,但我想它可以工作。我会根据我对你的目的的新理解来更新我的答案。
-
对我来说,不清楚这段代码应该做什么。也许你可以澄清你的意图,然后你可能会得到一个满足你要求的答案:)
-
@SebastianBusek 您能否指出任何答案是否足以解决您的问题,或者指出您还有哪些问题。或者,如果您找到了以不同方式自己解决问题的方法,请将其发布为答案。
标签: c# .net function lambda expression