C#转换为接口

C#转换为接口,c#,type-conversion,typing,C#,Type Conversion,Typing,是否可以定义如何将内置对象强制转换为C#中的接口?接口无法定义运算符。我有一个非常简单的接口,允许索引访问,但不允许变异: public interface ILookup<K, V> { V this[K key] { get; } } 公共接口ILookup { V此[K键]{get;} } 我希望能够将字典转换为ILookup。在我理想的梦境中,这看起来像: //INVALID C# public interface ILookup<K, V> {

是否可以定义如何将内置对象强制转换为C#中的接口?接口无法定义运算符。我有一个非常简单的接口,允许索引访问,但不允许变异:

public interface ILookup<K, V>
{
    V this[K key] { get; }
}
公共接口ILookup
{
V此[K键]{get;}
}
我希望能够将
字典
转换为
ILookup
。在我理想的梦境中,这看起来像:

//INVALID C#
public interface ILookup<K, V>
{
    static implicit operator ILookup<K, V>(Dictionary<K, V> dict)
    {
         //Mystery voodoo like code. Basically asserting "this is how dict
         //implements ILookup
    }
    V this[K key] { get; }
}
//无效的C#
公共接口ILookup
{
静态隐式运算符ILookup(字典dict)
{
//神秘的伏都教式代码。基本上是断言“这就是dict
//实现ILookup
}
V此[K键]{get;}
}
我的解决办法是:

public class LookupWrapper<K, V> : ILookup<K, V>
{
    private LookupWrapper() { }

    public static implicit operator LookupWrapper<K, V>(Dictionary<K, V> dict)
    {
        return new LookupWrapper<K, V> { dict = dict };
    }

    private IDictionary<K, V> dict;
    public V this[K key] { get { return dict[key]; } }
}
公共类查找说话者:ILookup
{
私有LookupRapper(){}
公共静态隐式运算符LookupRapper(字典Dictionary dict)
{
返回新的lookuprapper{dict=dict};
}
私人词典;
public V this[K key]{get{return dict[key];}
}
这很有效,意味着我现在可以直接从字典到ILookup进行转换,但男孩确实觉得很复杂


有更好的方法强制转换到接口吗?

由于接口不能包含实际代码,因此您需要一些类来“承载”转换的代码。这可以是实现接口的类(显然),否则它需要是一个包装类,就像您拥有的一样。没有第三个选项


“调用”强制转换的方式可能不同(例如,您可以在扩展方法后面隐藏
lookuprapper
的构造),但这不会改变任何事情。

如果您对字典有任何控制权,您可以将其子类化并覆盖
此[]
在你的子类中。然后使用你的新字典而不是.NET字典。

多亏@MBabcock的评论,我意识到我的想法是错误的。我将接口升级为完整的on类,如下所示:

public class Lookup<K, V>
{
    private readonly Func<K, V> lookup;
    protected Lookup(Func<K, V> lookup)
    {
        this.lookup = lookup;
    }

    public static implicit operator Lookup<K, V>(Dictionary<K, V> dict)
    {
        return new Lookup<K, V>(k => dict[k]);
    }

    public V this[K key]
    {
        get { return lookup(key); }
    }
}
公共类查找
{
私有只读函数查找;
受保护的查找(Func查找)
{
this.lookup=查找;
}
公共静态隐式运算符查找(字典dict)
{
返回新的查找(k=>dict[k]);
}
公共V本[K键]
{
获取{返回查找(键);}
}
}

我需要的任何进一步的转换都可以简单地添加一个隐式运算符

您最好使用扩展方法和包装类

public interface ILookup<K, V>
{
    V this[K key] { get; }
}

public class DictWrapper<K, V> : ILookup<K, V>
{
    Dictionary<K, V> dictionary;

    public DictWrapper(Dictionary<K, V> dictionary)
    {
        this.dictionary = dictionary;
    }

    public V this[K key]
    {
        get { return dictionary[key]; }
    }

    protected internal Dictionary<K, V> InnerDictionary { get { return dictionary; } }
}

public static class Extensions
{
    public static ILookup<K, V> ToLookup<K, V>(this Dictionary<K, V> dictionary)
    {
        return new DictWrapper<K, V>(dictionary);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, int> data = new Dictionary<string, int>();

        data.Add("Office", 100);
        data.Add("Walls", 101);
        data.Add("Stair", 30);

        ILookup<string, int> look = data.ToLookup();
    }
}
公共接口ILookup
{
V此[K键]{get;}
}
公共类:ILookup
{
字典;
公共词典(字典)
{
这本字典=字典;
}
公共V本[K键]
{
获取{返回字典[key];}
}
受保护的内部字典InnerDictionary{get{return Dictionary;}}
}
公共静态类扩展
{
公共静态ILookup ToLookup(本词典)
{
返回新的DictWrapper(字典);
}
}
班级计划
{
静态void Main(字符串[]参数)
{
字典数据=新字典();
数据。添加(“办公室”,100);
数据。添加(“墙”,101);
数据。添加(“楼梯”,30);
ILookup look=data.ToLookup();
}
}

这是一种非常恶劣的语言,但有一种方法。我假设您基本上试图将接口应用于一个已经具有所需签名的类,您只需要一个子集(如示例中所示)

您可以使用TransparentProxy/RealProxy对在运行时创建一个实现任何接口(或MarshalByRef对象)的类。您需要实现一个抽象方法来处理调用,但只需稍加改进,就可以使其足够通用,从而能够处理此类情况

我们在一个包装非常糟糕的库中遇到了类似的问题(我们必须使用反射来进行每个方法调用)。因此,我们没有编写大量自定义反射代码,而是编写了通用案例,然后编写了一系列与签名匹配的接口。然后我们直接使用这些接口。我们甚至自动包装/取消包装对象,这样我们就可以让我们的接口方法返回其他接口,这一切都可以正常工作


在您的环境中,有一个超长的方法论和一个实现

是否适合使用抽象类型而不是接口?还有其他比ILookup更合适的基类型……但现在我大声说出来,这没有多大意义……请随意将您的解决方案标记为答案,除非您不知道期待进一步发展guidence@M:2天后就可以了…(大多数情况下这是个好规则,但…*呃*)