简体   繁体   English

强制转换实现接口中所有方法的类

[英]Cast a class that implements all of the methods in an interface

If a class happens to implement all of the methods in an interface (but doesn't explicitly implement it), is there a way of casting an instance of the class to that interface? 如果一个类恰好实现了接口中的所有方法(但未明确实现),是否可以将类的实例强制转换为该接口?

To demonstrate the issue I've set up the following simple classes. 为了演示这个问题,我设置了以下简单的类。 Scavenger is a demonstration class that I want to unit test. Scavenger是我要进行单元测试的演示class

The IFinder interface can be implemented by a dictionary (or could be implemented some other way). IFinder interface可以由dictionary实现(或可以通过其他方式实现)。 Finder is a sample implementation of the interface using a dictionary to handle the lifting. Finder是使用字典来处理提升的接口的示例实现。

//System under test
public class Scavenger
{
    private readonly IFinder _lookup;

    public Scavenger(IFinder lookup)
    {
        _lookup = lookup;
    }

    public string WhatIs(string key)
    {
        if (_lookup.ContainsKey(key)) return _lookup[key];
        return null;
    }
}

//Interface that can be met by a dictionary
public interface IFinder
{
    bool ContainsKey(string key);
    string this[string key] { get; set; }
}


//Implement IFinder using a dictionary
public class Finder : Dictionary<string,string>, IFinder
{
    public Finder()
    {
        this.Add("A","Hello");
        this.Add("B","Goodbye");
    }
}

I'd hoped to be able to setup a test for Scavenger along these lines... 我希望能够按照以下方式为清道夫设置一个测试...

    /// <summary>
    /// This will fail because due to failed cast a Dictionary to an IFinder
    /// </summary>
    [TestMethod]
    public void LookupUsingDictionary()
    {
        var dic = new Dictionary<string, string>();
        dic.Add("A","B");
        var scavenger = new Scavenger(dic as IFinder);
        var res = scavenger.WhatIs("A");
        Assert.AreEqual("B", res);
    }

The issue is that (dic as IFinder) == null . 问题是(dic as IFinder) == null I know I can setup a mock class similar to Finder, or use a mocking framework, but I just want to check if I'm missing some way of casting a dictionary to do the job . 我知道我可以设置类似于Finder的模拟类,或使用模拟框架,但是我只想检查是否缺少某种铸造字典来完成这项工作的方法

When you have an interface and a class that implements all of the appropriate methods, but doesn't implement the interface, you can use the adaptor pattern to accopmlish your goal. 如果您有一个接口和一个实现所有适当方法的类,但没有实现该接口,则可以使用适配器模式来实现您的目标。 Create a class that implements the given interface and accepts an instance of the type that has all of the needed methods. 创建一个实现给定接口并接受具有所有必需方法的类型的实例的类。 It can then redirect all of the methods to the composed class: 然后,它可以将所有方法重定向到组成的类:

public class DictionaryFinder : IFinder
{
    private Dictionary<string, string> dictionary;
    public DictionaryFinder(Dictionary<string, string> dictionary)
    {
        this.dictionary = dictionary;
    }


    public bool ContainsKey(string key)
    {
        return dictionary.ContainsKey(key);
    }

    public string this[string key]
    {
        get { return dictionary[key]; }
        set { dictionary[key] = value; }
    }
}

This allows you to write: 这使您可以编写:

var scavenger = new Scavenger(new DictionaryFinder(dic));

No, you cannot do that. 不,你不能那样做。 That's called duck typing and C# does not allow that. 这就是所谓的鸭子输入,而C#不允许这样做。

You can use the dynamic keyword to accomplish this... 您可以使用dynamic关键字来完成此任务...

Make your scavenger class like this: 使您的清除剂类如下所示:

public class Scavenger
{
    private readonly dynamic _lookup;

    public Scavenger(dynamic lookup)
    {
        _lookup = lookup;
    }

    public string WhatIs(string key)
    {
        if (_lookup.ContainsKey(key)) return _lookup[key];
        return null;
    }
}

This will attempt to find the methods at runtime instead. 这将尝试在运行时查找方法。 See more at: http://msdn.microsoft.com/en-us/library/dd264741.aspx 有关更多信息,请访问: http : //msdn.microsoft.com/zh-cn/library/dd264741.aspx

You might be able to use ImpromptuInterface . 您也许可以使用ImpromptuInterface I've used it to essentially do duck typing-like behavior. 我用它来做类似鸭子打字的行为。

C# does allow duck typing, to some degree, thanks to the dynamic language runtime introduced in 4.0 (I believe it was 4.0), just be very careful you don't burn yourself. 由于在4.0(我相信是4.0)中引入了动态语言运行时,因此C#确实允许在某种程度上进行鸭子类型的输入,请务必小心,不要烧伤自己。 ImpromptuInterface is proof of this. ImpromptuInterface就是证明。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 查找类实现的所有接口 - Finding all Interface that a class implements 如何检查类是否在NRefactory中实现接口方法 - How to check if a class implements interface methods in NRefactory c#实现接口的类中的虚方法 - c# virtual methods in class that implements interface C#:有没有一种方法可以将类强制转换为在运行时实现的接口,而不是在编译时实现的接口? - C#: Is there a way to cast a class to an interface it implements at runtime, but not compile time? 如何从实现接口的类中调用新方法 - How to call new methods from a class which implements interface 是否可以将私有专用方法添加到实现特定接口的类中? - Is it possible to add private use only methods to a class that implements a certain interface? 向实现已知接口的未知类的特定实例添加扩展方法 - Add extension methods to specific instantiations of unknown class that implements a known interface 实现所有实现的接口 - Interface that implements all it realizations 如何将通过接口标识的对象转换为实现该接口的泛型类的特定对象 - How to cast an object identified via an interface to the specific object of a Generic class that implements that interface foreach循环无法将类型转换为它实现的接口 - foreach loop can not cast type to the interface it implements
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM