简体   繁体   English

C#接口方法声明-无法执行实现

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

I have a concrete class implementation of an interface that has a method declaration like so.... 我有一个接口的具体类实现,该接口具有这样的方法声明。

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

All fairly straight forward. 一切都相当简单。 Declare an interface and implement from a concrete class. 从一个具体的类声明一个接口并实现。 However when I try to call the LocalResource method of the concrete class I get an exception. 但是,当我尝试调用具体类的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();
      }
}

The exception occurs when trying to execute the LocalResource() method (highlighted above). 尝试执行LocalResource()方法时发生异常(上面突出显示)。

{System.InvalidCastException: Unable to cast object of type '<LocalResource>d__0' to type 'System.Collections.Generic.Dictionary`2[System.String,System.String]'. {System.InvalidCastException:无法将类型为“ <LocalResource> d__0”的对象转换为类型为“ System.Collections.Generic.Dictionary`2 [System.String,System.String]”。 at FantasyLeague.Web.Mvc.ControllerContentBuilder.BuildT in C:\\Users\\andrew.knightley\\git\\FAST\\src\\ContentManagement\\FantasyLeague.Web.Mvc\\ControllerBase.cs:line 290} 在FantasyLeague.Web.Mvc.ControllerContentBuilder.BuildT中,位于C:\\ Users \\ andrew.knightley \\ git \\ FAST \\ src \\ ContentManagement \\ FantasyLeague.Web.Mvc \\ ControllerBase.cs:line 290}

Basically it appears that C# is trying to parse the interface method signature as a Dictionary, hence the error, however surely it should be trying to execute the concrete implementation. 基本上看来,C#试图将接口方法签名解析为Dictionary,因此出现了错误,但是可以肯定的是,它应该尝试执行具体的实现。 Anyone know whats going on here? 有人知道这是怎么回事吗? I've tried casting to interface and concrete type and all combinations, it still isn't having it. 我已经尝试过转换为接口和具体类型以及所有组合,但仍然没有。 I have reread all the MSDN stuff on interfaces, according to their articles there is nothing out of the ordinary here. 我已经重读了接口上的所有MSDN内容,根据他们的文章,这里没有什么异常之处。

Many thanks in advance. 提前谢谢了。

Simply put, your implementation isn't returning a Dictionary<string, string> , so you can't cast to it. 简而言之,您的实现不会返回Dictionary<string, string> ,因此您无法将其强制转换为它。 You're just returning a sequence of key/value pairs - that's not the same thing as a dictionary. 您只是返回键/值对的序列-与字典不同。

Note that this has nothing to do with the method being declared on an interface - you're calling the right implementation, but just casting the result. 请注意,这与在接口上声明的方法无关-您在调用正确的实现,而只是强制转换结果。 You can see this by separating the two: 您可以通过将两者分开来查看:

IEnumerable<KeyValuePair<string, string>> tmp = controllerContent.LocalResource();
controllerContent.CDict = (Dictionary<string, string>) tmp; // Bang!

The simplest fix would be to create a dictionary with LINQ: 最简单的解决方法是使用LINQ创建字典:

controllerContent.CDict = controllerContent.LocalResource()
                                           .ToDictionary(x => x.Key, x => x.Value);

Note that an alternative implementation of your LocalResource() method could also use LINQ: 请注意,您的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));
}

That will end up boxing each DictionaryEntry , but it's somewhat simpler than your iterator block approach, IMO. 最终将每个DictionaryEntry装箱,但是它比您的迭代器块方法IMO简单。

The problem is with the cast from the results of your method -> Dictionary<string,string> 问题在于方法结果的类型转换-> Dictionary<string,string>

Try the following code in LinqPad to see the issue. 在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");
}

You can't cast directly from an IEnumerable<KeyValuePair<string,string>> to Dictionary<string,string> . 您不能直接从IEnumerable<KeyValuePair<string,string>>Dictionary<string,string>

Try changing your conversion to the following 尝试将转换更改为以下内容

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