繁体   English   中英

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

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

如果一个类恰好实现了接口中的所有方法(但未明确实现),是否可以将类的实例强制转换为该接口?

为了演示这个问题,我设置了以下简单的类。 Scavenger是我要进行单元测试的演示class

IFinder interface可以由dictionary实现(或可以通过其他方式实现)。 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");
    }
}

我希望能够按照以下方式为清道夫设置一个测试...

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

问题是(dic as IFinder) == null 我知道我可以设置类似于Finder的模拟类,或使用模拟框架,但是我只想检查是否缺少某种铸造字典来完成这项工作的方法

如果您有一个接口和一个实现所有适当方法的类,但没有实现该接口,则可以使用适配器模式来实现您的目标。 创建一个实现给定接口并接受具有所有必需方法的类型的实例的类。 然后,它可以将所有方法重定向到组成的类:

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

这使您可以编写:

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

不,你不能那样做。 这就是所谓的鸭子输入,而C#不允许这样做。

您可以使用dynamic关键字来完成此任务...

使您的清除剂类如下所示:

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

这将尝试在运行时查找方法。 有关更多信息,请访问: http : //msdn.microsoft.com/zh-cn/library/dd264741.aspx

您也许可以使用ImpromptuInterface 我用它来做类似鸭子打字的行为。

由于在4.0(我相信是4.0)中引入了动态语言运行时,因此C#确实允许在某种程度上进行鸭子类型的输入,请务必小心,不要烧伤自己。 ImpromptuInterface就是证明。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM