当前位置: 首页 > 编程语言 > C#

是否可以为类型参数指定泛型约束以从另一种类型转换?分享

时间:2023-04-10 23:54:52 C#

是否可以为类型参数指定泛型约束以从另一种类型转换?假设我编写了一个包含以下内容的库:publicclassBar{/*...*/}publicclassSomeWeirdClasswhereT:???{publicTBarMaker(Barb){//...玩bTt=(T)breturn(T)b;稍后,我希望用户通过定义自己的类型来使用我的库,这些类型可以转换为Bar并使用SomeWeirdClass“工厂”。publicclassFoo{publicstaticexplicitoperatorFoo(Barf){returnnewBar();}}publicclassDemo{publicstaticvoiddemo(){Barb=newBar();SomeWeirdClass很奇怪=newSomeWeirdClass();Foof=weird.BarMaker(b);如果我设置whereT:Foo这将编译,但问题是我在库的编译时不知道Foo,我实际上想要更像whereT的东西:一些可以实例化的类,给定一个Bar是这可能吗?从我有限的知识来看,它似乎不是,但.NETFramework及其用户的独创性总是让我感到惊讶......它可能与静态接口方法的概念有关-至少,我可以看到能够指定存在一个工厂方法来创建对象的值(类似于你已经可以做的whereT:new())编辑:解决方案-感谢尼克和bzIm-对于其他读者,我将提供一个完整的解决方案我明白了:edit2:这个解决方案需要Foo公开一个公共默认构造函数。对于不需要这个的更愚蠢更好的解决方案,请参阅本文的最底部。publicclassBar{}publicclassSomeWeirdClass其中T:IConvertibleFromBar,new(){publicTBarMaker(Barb){Tt=newT();t.Convert(b);返回吨;}}publicinterfaceIConvertibleFromBar{TConvert(Barb);}publicclassFoo:IConvertibleFromBar{publicstaticexplicitoperatorFoo(Barf){returnnull;}publicFooConvert(Barb){return(Foo)b;}}publicclassDemo{publicstaticvoiddemo(){Barb=newBar();SomeWeirdClass很奇怪=newSomeWeirdClass();Foof=weird.BarMaker(b);}}edit2:解决方案2:创建一个类型转换工具工厂使用:#regionlibrarydefinedcodepublicclassBar{}publicclassSomeWeirdClasswhereTFactory:IConvertorFactory,new(){privatestaticTFactoryconvertor=newTFactory();publicTBarMaker(Barb){returnconvertor.Convert(b);}}publicinterfaceIConvertorFactory{TToConvert(TFromfrom);}#endregion#region用户定义代码publicclassBarToFooConvertor:IConvertorFactory{publicFooConvert(Barfrom){返回(Foo)从;}}publicclassFoo{publicFoo(inta){}publicstaticexplicitoperatorFoo(Barf){returnnull;}publicFooConvert(Barb){return(Foo)b;}}#endregionpublicclassDemo{publicstaticvoiddemo(){Barb=newBar();SomeWeirdClass很奇怪=newSomeWeirdClass();Foof=weird.BarMaker(b);我认为这种语法是内置在语言中的,不一定有语法上很酷的方法。您的问题的可能解决方案可能是定义一个可转换接口:publicinterfaceIConvertiblewhereT:new()//Probablywillneedthis{TConvert();那么你的课程可能是:publicclassFoo:IConvertible{}我认为这让你接近你想要的地方......你问题中的所有Foo和Bar有时很难确定你的意图。希望这可以帮助。编辑:添加约束...您可能必须能够在可转换类中创建一个新实例。编辑2:从ICovertible获取Fooinheritance听起来您找到了解决更大问题的方法。要回答您的具体问题:不,C#和CLR都不支持“向后”泛型类型参数约束。也就是说,不支持C类,其中Foo:T“T必须是Foo或Foo转换为的类型”。有些语言有这个约束;IIRCScala就是这样一种语言。我怀疑此功能对于逆变器接口的某些用途会很方便。您可以通过使用接口作为类型约束来绕道而行。例如,使用whereT:IComparable将类型限制为可以与另一事物进行比较的类型必须通过实现IComparable来表达此功能。如果你有一个接口ICastableFrom,你可以通过强制他们实现ICastableFrom来实现你想要的。与其经历定义接口和修改类来实现该接口的麻烦,何乐而不为呢?publicclassSomeWeirdClass{//旁白:如果此方法返回T,为什么称为“BarMaker”?publicTBarMaker(Barb,Funcconverter){//...玩breturnconverter(b);那么,如果你处理的是一个可以直接转换为Bar的T类型的对象,你可以这样调用这个方法:varsomeWeirdObject=newSomeWeirdClass();varsomeBar=newBar();varsomeFoo=someWeirdObjcet.BarMaker(someBar,bar=>barasFoo);顺便说一下(因为Func委托出现在.NET3.5中),您还可以使用转换器(完全相同)作为转换器参数。以上是C#学习教程:Isitpossibletospecifyageneralconstraintforatypeparametertoconvertfromanothertype?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: