C# 在c中将一种任意类型转换为另一种类型的通用方法#

C# 在c中将一种任意类型转换为另一种类型的通用方法#,c#,generics,C#,Generics,我想这样做: public static TResult MyCast<TSource, TResult>(TSource item) { return (TResult)item; } 在与同事讨论之后,似乎没有简单的方法来实现这样的功能(如果可能的话),因此我一直在为不同的情况(即引用类型的向上和向下转换以及某些值类型的转换)使用几种非常简单的方法的代码膨胀:( 太糟糕了,我不能使用.NET 4.0,因为它具有动态性等优点。如何 x=MyCast(y) 比 x=(Res

我想这样做:

public static TResult MyCast<TSource, TResult>(TSource item)
{
    return (TResult)item;
}
在与同事讨论之后,似乎没有简单的方法来实现这样的功能(如果可能的话),因此我一直在为不同的情况(即引用类型的向上和向下转换以及某些值类型的转换)使用几种非常简单的方法的代码膨胀:(

太糟糕了,我不能使用.NET 4.0,因为它具有
动态性
等优点。

如何
x=MyCast(y)



x=(ResultType)y

TSource
TResult
都是引用类型时,这很简单

如果其中一个是值类型,您希望它如何工作?值类型不能相互继承,因此不需要进行上转换或下转换。您可能希望在
int
double
之间进行数字转换,但您必须自己对其进行编码:.NET不会将它们视为类型转换。并且转换是正确的比如说,
DateTime
string
之间涉及更多的智能(什么格式?哪种文化?等等)

如果您只是处理引用类型,那么此方法可以是一个单行程序。如果您也想处理值类型,那么您需要为各种组合编写特殊的案例代码


Edit:在封装值类型之间的各种转换方面做得很好。但是你提到你不想引入装箱:
Convert。ChangeType
不是泛型的,它需要一个
对象
我认为你试图解决的问题与你不能解决的问题是一样的t将一种类型的集合强制转换为另一种类型的集合。 乙二醇

类Obj1
{}
Obj2类:Obj1
{}
List srcList=GetList();
List castedList=(List)srcList;//此行无法编译

我没有做太多的实际研究CLR代码 然而,在它像C++的情况下,你会得到的是存储在集合中的不同的值。换句话说,SRCLIST将包含一个指向CASTEDLIST中对象2接口的指针列表,你将有一个指针指向对象2内对象1的接口。 为了解决此问题,您需要让强制转换函数迭代集合中的每个项。但是,为了能够迭代这些项,列表必须实现某种枚举接口。因此,枚举接口需要是强制转换函数的约束

因此答案是否定的

但是,如果您准备通过对in类型的限制来实现此功能,则您可以:

静态类ListCast
其中t来源:IEnumerable
其中TResult:IList,new()
{
静态TResult Cast(TSource list)
{
TResult castedList=newTResult();
foreach(列表中的TtemType项)
{
castedList.添加(滴度类型)项);
}

返回castedList;
}
}

您可以这样做:

public static TResult MyCast<TSource, TResult>(TSource item)
{
    return (TResult)((object)item);
}
publicstatictresultmycast(TSource项)
{
返回(TResult)((对象)项);
}

我很想知道这有多糟糕。

看看。可能会给你一些想法。谢谢,但这对我的情况不是很有用(实际上,你应该很高兴你不能使用.NET 4.0和dynamic,因为你的计划很糟糕。你必须在没有公共基类的不同类型层次结构之间转换,这是一种非常糟糕的代码味道,再多的动态也掩盖不了这一点。考虑到我一直在使用遗留代码库,现在需要做cross调用时,我宁愿使用我的小型转换例程,也不愿重新实现它们。通常,您作为MyCast(对象输入)来执行因为您希望在带有反射的泛型调用中使用它来进行动态强制转换。我看不出使用这种方法的原因。这是一个简化的示例。我实际需要的是这样的方法:public static Dictionary CastValues(This Dictionary Dictionary)@13xforever:使用Cast和OfType扩展方法如何?@simendsjo:这只适用于某些情况,如果它们适用,我显然不需要编写一些愚蠢的包装来调用它们。我只对通常在开发过程中执行的显式转换感兴趣(换句话说,我不希望它足够智能,可以在类型之间进行自定义转换)。即使考虑引用类型,我也想不出一个方法可以同时执行向上和向下转换(好吧,在4.0之前的CLR中不是这样).总而言之,这就是我为什么要问的原因。现在我使用ATM的所有类型都有自定义的泛型方法。它们都非常简单,而且做的事情完全相同。这只是…令人不安。“开发期间通常执行的显式强制转换”-这些实际上是C#编译器实现的规则。所有类型转换的语法都是相同的,但编译器知道如何在各种数字类型之间转换;它为不同的类型对生成不同的IL。在
MyCast
方法中,您需要自己重新实现这些规则。是的,我知道。这只是DLR proNET 4.0中引入的totype在某种程度上是一个独立的项目,运行在CLR之上,因此我认为可能有一种相当简单的方法来执行运行时强制转换:DHmm--
Convert.ChangeType
,但我想这也不太理想。感谢
Convert.ChangeType
。即使它在这方面没有多大用处无论如何,这是这里最有用的知识。没关系。我不想研究复杂的类型转换解决方案。我只想进行运行时类型转换。在这一点上,我非常确定没有任何简单的解决方案。>不限制TSource或TResult,并尽可能避免不必要的装箱。
public static TResult MyCast<TSource, TResult>(TSource item)
{
    return (TResult)((object)item);
}