Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无约束型参数铸造_C#_.net_Types_Casting - Fatal编程技术网

C# 无约束型参数铸造

C# 无约束型参数铸造,c#,.net,types,casting,C#,.net,Types,Casting,我的情况: interface ISomeInterface { void DoSmth<T>(T other); } class Base : ISomeInterface { public virtual void DoSmth<T>(T other){ // for example do nothing } } class Derived<T2> : Base { Action<T2> My

我的情况:

interface ISomeInterface {
    void DoSmth<T>(T other);
}

class Base : ISomeInterface
{
    public virtual void DoSmth<T>(T other){
        // for example do nothing
    }
}

class Derived<T2> : Base {
    Action<T2> MyAction {get;set;}

    public override void DoSmth<T>(T other){
        if(typeof(T2).IsAssignableFrom(typeof(T)))
            MyAction((T2) other);
    }
}
接口接口{
无效剂量(T其他);
}
类基:接口
{
公共虚拟无效数据(T其他){
//比如什么都不做
}
}
派生类:基{
动作MyAction{get;set;}
公共覆盖无效DoSmth(T其他){
if(typeof(T2).IsAssignableFrom(typeof(T)))
我的行动((T2)其他);
}
}
这给了我一个错误:
无法将类型“T”的表达式强制转换为类型“T2”
(或者
无法将类型“T”转换为“T2”


我理解这是因为T或T2都不受
类的约束,但如果我知道-由于
是可从
中识别的-我可以在需要T2的地方使用T,我如何说服编译器允许它呢?

编译器会看到T2和T标识符,并有助于通知您这些类型似乎不相关。这是绝对正确的,因为它们没有关系:没有任何通用约束可以断言它们之间的任何关系(但我并不是说这在这里有用:)

这是不是一个好的功能,是有争议的。有时我希望它只是一个警告,但在大多数情况下,将其作为编译错误是有帮助的。泛型类中此类类型转换的数量远低于“普通”代码中的打字错误数量:)

解决方案非常简单。只要欺骗编译器,使其对源类型一无所知,它就会跳过针对目标类型的类型层次结构检查:

T theTee = ...;
object temp = (object)theTee;
T2 teeTwo = (T2)temp; // ok! 'temp' is now seen as 'object'
或在一个班轮中:

T2 teeTwo = (T2)(object)theTee;
类似地,您可以使用
动态
(如果.Net版本中有):

而oneliner也应该起作用:

T2 teeTwo = (dynamic)theTee;

虽然我从来没有试过那个,因为我认为它比通过物体铸造的要重。不过,我还没有检查对象/动态方法的性能。只是一个预感。

(T2)(对象)其他
(T2)(对象)其他
(T2)(对象)其他
是的,你们是对的-我在发布几秒钟后就有了这个想法;)写一个答案,我会接受:)在Java中,您可以给T和T2一个公共接口,并使用它。这在这里也有帮助吗?正如我第一次读到关于dynamic的文章时所想的那样,从性能角度来看,它可能更糟糕。我想我会选择(T2)(对象)——我已经添加了一条评论,向“未来几代”解释我自己。如果我只是在
IsAssignableFrom==true
之后才这样做,那么它应该总是有效的,不是吗?根据我的记忆,
IsAssignableFrom
是你能得到的最好的类型vs类型检查。然而,
IsAssignableFrom
vs
IsCastable
这个名称不时会困扰我。我不记得任何情况下,
AssignableFrom
不会导致
可铸造性
。我不能告诉你我绝对肯定。我能想到一些非常罕见的情况,在这些情况下可能会发生一些奇怪的事情,但是,我看不到也不记得有任何情况是不起作用的。@Gerino:所以,我坚信,
IsAssignableFrom
在这个方向上意味着“可铸造性”。然而,这些条件并不平等。我相信,
IsAssignableFrom
至少可以让你得到一些误判。例如,一个
\uuu-ComObject
实际上可以在运行时强制转换为接口,但我认为它的类型不会是
IsAssignableFrom
转换为这些接口类型。但从来没有检查过。查看msdn文章可能会很有意思。嗯,COM的误报似乎是一个事实——幸运的是,正如我所说,我从来没有听说过误报:)我想,当我找到它时,我会跨越这座桥——类型应该是相当非外来的(原语,模型类),老实说,在大多数情况下,T==T2-我不想让它有更通用的实现,例如,
Model:ModelBase
OtherModel:ModelBase
:)
T2 teeTwo = (dynamic)theTee;