簡體   English   中英

C#接口方法聲明-無法執行實現

[英]C# interface method declaration - cannot execution implemention

我有一個接口的具體類實現,該接口具有這樣的方法聲明。

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中,位於C:\\ Users \\ andrew.knightley \\ git \\ FAST \\ src \\ ContentManagement \\ FantasyLeague.Web.Mvc \\ ControllerBase.cs:line 290}

基本上看來,C#試圖將接口方法簽名解析為Dictionary,因此出現了錯誤,但是可以肯定的是,它應該嘗試執行具體的實現。 有人知道這是怎么回事嗎? 我已經嘗試過轉換為接口和具體類型以及所有組合,但仍然沒有。 我已經重讀了接口上的所有MSDN內容,根據他們的文章,這里沒有什么異常之處。

提前謝謝了。

簡而言之,您的實現不會返回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簡單。

問題在於方法結果的類型轉換-> 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM