system.ArgumentNullexception in ResourceManager.getString内部
-
29-09-2019 - |
题
我的代码:
System.Resources.ResourceManager resourceManager = GetResourceManager();
string str = resourceManager.GetString("delete", new CultureInfo(1033));
在当前的项目中,根据.NET 2.0编译,所有内容均可用除外。多变的 str 包含用于LCID 1033-的资源字符串 - 删除, , 还行吧。
我们现在正在升级到.NET 4.0,在目标框架.NET 4.0下重新编译了项目。现在编译为.NET 4.0组件,它引发了异常 System.ArgumentNullexception 带有消息 值不能为null。。堆栈跟踪:
at System.Threading.Monitor.Enter(Object obj)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo requestedCulture, Boolean createIfNotExists, Boolean tryParents, StackCrawlMark& stackMark)
at System.Resources.ResourceManager.InternalGetResourceSet(CultureInfo culture, Boolean createIfNotExists, Boolean tryParents)
at System.Resources.ResourceManager.GetString(String name, CultureInfo culture)
有趣的是StackTrace,它指向内部框架方法 ResourceManager.internalgetResourceset 这会导致打电话 Monitor.enter 使用null对象。但是我叫方法 Getstring 没有null参数 getString(“删除”,新cultureinfo(1033)).
这个错误似乎与 system.ArgumentNullexception in System.Threading.Monitor.enter. 。也许在Monitor.enter中或其他错误?
更新:当我在调试器上查看对象时 resourceManager.ResourceSets.Items[2].Value.Table["delete"]
然后它包含字符串值“ delete”。属性项目[2]指向LCID 1033.这意味着资源管理器已经包含资源密钥的本地化字符串 删除 语言 1033. 。有人知道哪里可能是错误吗?
解决方案
我还认为您应该声明并使用自己的字典作为存储
其他提示
我发现自己答案。以下是详细信息:我们有这样的自定义实现资源管理器:
public class DatabaseResourceManager : System.Resources.ResourceManager
{
public DatabaseResourceManager(int applicationID, string bundle)
{
foreach (int languageID in ResourceProvider.Provider.GetLanguages(applicationID))
{
DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, languageID);
ResourceSets.Add(new CultureInfo(languageID), new ResourceSet(r));
}
}
在.NET 2.0中,它运行良好,但是在.NET 4.0中,在ResourceManager的实现中发生了变化。我认为该问题是在.NET 2.0中实例化私有字段中的无参数构造函数 this._resourcesets (后来使用 InternalGetResourceset 用于Monitor.enter)。但是.NET 4.0无参数构造函数不能实例化私有字段 this._resourcesets 因此,它以后失败(如Abobe所述)。
我必须重写我的自定义资源经理以解决:
public class DatabaseResourceManager : System.Resources.ResourceManager
{
public DatabaseResourceManager(int applicationID, string bundle)
{
ResourceSets = new Hashtable();
this.applicationID = applicationID;
this.bundle = bundle;
}
protected override ResourceSet InternalGetResourceSet(CultureInfo culture, bool createIfNotExists, bool tryParents)
{
if (this.ResourceSets.Contains(culture.Name))
return this.ResourceSets[culture.Name] as ResourceSet;
lock (syncLock)
{
if (this.ResourceSets.Contains(culture.Name))
return this.ResourceSets[culture.Name] as ResourceSet;
DatabaseResourceReader r = new DatabaseResourceReader(applicationID, bundle, culture.LCID);
ResourceSet rs = new ResourceSet(r);
this.ResourceSets.Add(culture.Name, rs);
return rs;
}
}
}
“魔术”这是我必须覆盖方法 InternalGetResourceset 从自定义存储(DB)加载我的资源,然后返回“资源集”以进行指定文化。现在它就像魅力一样。