我有一个具有类似方法声明的接口的具体类实现....
public interface IControllerContent
{
IEnumerable<KeyValuePair<string, string>> LocalResource();
}
public class BaseControllerContent : IControllerContent
{
public IEnumerable<KeyValuePair<string, string>> LocalResource()
{
ResourceSet resourceSet =
ResourceManager.GetResourceSet(new CultureInfo(this.Tenant.Locale), true, false);
IDictionaryEnumerator dictionaryEnumerator = resourceSet.GetEnumerator();
while (dictionaryEnumerator.MoveNext())
{
//only string resources
var value = dictionaryEnumerator.Value as string;
if (value != null)
{
var key = (string)dictionaryEnumerator.Key;
yield return new KeyValuePair<string, string>(key, value);
}
}
}
}
一切都相当直接。从具体类声明接口和实现。 但是当我尝试调用具体类的LocalResource方法时,我得到了一个异常。
public T Build<T>() where T : class, IControllerContent
{
var controllerContent = Activator.CreateInstance(typeof(T)) as T;
try
{
**controllerContent.CDict = (Dictionary<string, string>) controllerContent.LocalResource();**
controllerContent.CDict = (Dictionary<string, string>) JsonReader<T>.Parse(this.Content);
return controllerContent;
}
catch (Exception ex)
{
throw new Exception();
}
}
尝试执行LocalResource()方法时出现异常(上面突出显示)。
{System.InvalidCastException:无法将类型为'&lt; LocalResource&gt; d__0'的对象强制转换为'System.Collections.Generic.Dictionary`2 [System.String,System.String]'。 at幻想联盟.Web.Mvc.ControllerContentBuilder.BuildT在C:\ Users \ andrew.knightley \ git \ FAST \ src \ ContentManagement \ FantasyLeague.Web.Mvc \ ControllerBase.cs:第290行}
基本上,C#似乎试图将接口方法签名解析为Dictionary,因此错误,但肯定应该尝试执行具体实现。 有谁知道这里发生了什么? 我已经尝试过铸造接口和具体类型以及所有组合,它仍然没有它。 我已经重读了接口上的所有MSDN内容,根据他们的文章,这里没有任何异常。
非常感谢提前。
答案 0 :(得分:3)
简单地说,您的实现不是返回Dictionary<string, string>
,因此您无法转换它。你只是返回一系列键/值对 - 这与字典不同。
请注意,这与在接口上声明的方法无关 - 您调用正确的实现,但只是转换结果。您可以通过将两者分开来看到这一点:
IEnumerable<KeyValuePair<string, string>> tmp = controllerContent.LocalResource();
controllerContent.CDict = (Dictionary<string, string>) tmp; // Bang!
最简单的解决方法是使用LINQ创建一个字典:
controllerContent.CDict = controllerContent.LocalResource()
.ToDictionary(x => x.Key, x => x.Value);
请注意,LocalResource()
方法的替代实现也可以使用LINQ:
public IEnumerable<KeyValuePair<string, string>> LocalResource()
{
ResourceSet resourceSet = ResourceManager.GetResourceSet(
new CultureInfo(this.Tenant.Locale), true, false);
return resourceSet.Cast<DictionaryEntry>()
.Where(de => de.Value is string)
.Select(de => new KeyValuePair((string) de.Key,
(string) de.Value));
}
这将最终装箱每个DictionaryEntry
,但它比你的迭代器块方法IMO稍微简单。
答案 1 :(得分:0)
问题在于您的方法结果中的强制转换 - &gt; Dictionary<string,string>
在LinqPad中尝试以下代码以查看问题。
void Main()
{
Dictionary<string, string> results = (Dictionary<string, string>)GetResults();
}
public IEnumerable<KeyValuePair<string, string>> GetResults()
{
yield return new KeyValuePair<string,string>("a", "a");
yield return new KeyValuePair<string,string>("b", "b");
yield return new KeyValuePair<string,string>("c", "c");
}
您无法直接从IEnumerable<KeyValuePair<string,string>>
投射到Dictionary<string,string>
。
尝试将转换更改为以下
var x = GetResults();
Dictionary<string, string> results = x.ToDictionary(y => y.Key, y => y.Value);