如果需要将泛型类型参数强制转换为特定类型,我们可以将其强制转换为对象,并按如下所示执行强制转换:
void SomeMethod(T t)
{
SomeClass obj2 = (SomeClass)(object)t;
}
是否有更好的方法来实现这一点,而不是将其强制转换为对象,然后再转换为特定类型?
问题:
我有一个泛型函数,它接受一个泛型类型参数,在函数内部,基于类型检查,我做了如下操作:
void SomeMethod(T t)
{
if (typeof(T).Equals(typeof(TypeA)))
{
TypeA = (TypeA)(object)t;
//Do some operation
}
else if (typeof(T).Equals(typeof(TypeB)))
{
TypeB = (TypeB)(object)t;
//Do some operation
}
}
9条答案
按热度按时间qltillow1#
您可以使用Convert.ChangeType
不过,请记住,如果强制转换无效,这将引发异常。
fzsnzjdm2#
使用
as
:这不会引发异常,并且如果转换失败,
t
将为null。我真的不知道你想做什么,但我希望你没有错过泛型的重点。
如果要将方法限制为
SomeClass
及其后代类型:8fsztsew3#
一个更好的设计是对它施加一个约束,该约束在类型T和您希望在方法中使用的类之间是通用的,在本例中是
SomeClass
。根据问题的编辑进行编辑
这是一个糟糕的设计。试着把那个“操作”移到类本身中,这样调用者就不必知道类型了。如果这不可能共享更多正在做的事情,那么你想要实现的是,你没有一个if/else语句的堆栈,在那里执行依赖于传递给方法的对象的类型。
mum43rcc4#
无意中发现了这个问题,并希望为以后发现这个问题的其他人提供一个更新的答案。在较新的C#版本中(在我写这篇文章时是8.0),pattern matching将允许您以一种更简洁的方式来完成这个任务:
这将检查对象的类型,如果找到匹配项,将在一个步骤中将其赋值给指定的变量,然后该变量就可以在case的主体中使用了。(您也可以在if语句中执行类似的操作:x1月1x)
尽管如此,我还是同意其他人的回答,即您应该尽可能地约束这个操作(
void SomeMethod<T>(T t) where T : ISomeInterface {...}
),或者如果可能的话,将操作移到您正在测试的类中。s71maibg5#
对于这种情况,可以使用
as
3npbholx6#
如果在输入类型
T
和目标类型TypeA
或TypeB
之间没有关系(使用参数约束),并且我们纯粹地查看强制转换问题,则答案很简单:不,没有比您正在使用的方法更好的方法了!!!
我确实同意其他一些人的观点,如果你在那个物体上做更多的操作,你可能会想选择一个不同的设计。
rm5edbpk7#
我知道这是一个迟来的问题,但在这里你可以做什么
一个很好的选择是让您的函数接受类
object
的参数,并根据需要切换大小写你只管选演员
vu8f3i0k8#
这个简单的破解就能解决所有问题吗?:
是的,这样编译器就不会发现强制转换问题,我们创建的对象会使GC有点紧张,但它很容易编写和理解。
当然,你可以在Cast操作符的实现中复制你需要的位,但我猜大多数人不会理解代码的内容,所以如果你需要更高的性能,你可以得到更多,但在大多数情况下应该工作得很好。
0pizxfdo9#
我有一个继承自另一个类A的类B,Convert.ChangeType失败,并显示“Object must implementing IConvertible.”System.InvalidCastException.但我可以用不同的方法来做:
这里的诀窍是我先把变量retObj设置为一个对象变量,然后我可以把对象变量转换成我想要的基类。这比我想做的任何其他黑客都要容易和干净得多!
这对微软来说似乎很容易。