C#转换为接口
是否可以定义如何将内置对象强制转换为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> {
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天后就可以了…(大多数情况下这是个好规则,但…*呃*)