0

私はそのようなメソッド宣言を持つインターフェースの具体的なクラス実装を持っています....

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: タイプ '<LocalResource>d__0' のオブジェクトをタイプ 'System.Collections.Generic.Dictionary`2[System.String,System.String]' にキャストできません。FantasyLeague.Web.Mvc.ControllerContentBuilder.BuildT in C:\Users\andrew.knightley\git\FAST\src\ContentManagement\FantasyLeague.Web.Mvc\ControllerBase.cs:line 290}

基本的に、C# はインターフェイス メソッドのシグネチャをディクショナリとして解析しようとしているように見えるため、エラーが発生しますが、具体的な実装を実行しようとしているはずです。ここで何が起こっているか知っている人はいますか?インターフェイスと具象型、およびすべての組み合わせにキャストしようとしましたが、まだありません。インターフェイスに関するすべての MSDN の内容を読み直しました。記事によると、ここには何も異常はありません。

よろしくお願いします。

4

2 に答える 2

3

簡単に言えば、あなたの実装は を返さDictionary<string, string>ないので、それにキャストすることはできません。キーと値のペアのシーケンスを返すだけです。これは辞書とは異なります。

これは、インターフェイスで宣言されているメソッドとは関係がないことに注意してください。正しい実装を呼び出していますが、結果をキャストしているだけです。これは、2 つを分離することで確認できます。

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

それは each をボクシングするDictionaryEntryことになりますが、イテレータブロックのアプローチである IMO よりもいくらか簡単です。

于 2013-09-18T11:19:45.790 に答える
0

問題は、メソッドの結果からのキャストにあります->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>>toから直接キャストすることはできませんDictionary<string,string>

変換を次のように変更してみてください

var x = GetResults();
Dictionary<string, string> results  = x.ToDictionary(y => y.Key, y => y.Value);
于 2013-09-18T11:23:30.450 に答える