我想做这样的事情:
public static TResult MyCast<TSource, TResult>(TSource item)
{
return (TResult)item;
}
对TSource或TResult没有限制,如果可能的话避免不必要的拳击。
编辑:我想强调一点,我想要一个简单的类型转换,而不是精心设计的类型转换。在施法时失败是完全可以的,比如说string
到int
。
使用CLR 2.0是否有任何理智的方法?
编辑:这是一个简化版本,所以它没用,是的。 但考虑转换泛型集合,例如:
public static Dictionary<string, TResult> CastValues<TSource, TResult>(this Dictionary<string, TSource> dictionary)
在与我的同事讨论之后,似乎没有简单的方法来实现这样的功能(如果可能的话),所以我坚持使用几种非常简单的方法来解决不同情况(即向上) - 引用类型的转发和某些值类型的转换):(
太糟糕了我无法使用.NET 4.0及其所有dynamic
等等。
答案 0 :(得分:7)
怎么会
x = MyCast<SourceType, ResultType>(y)
比任何更有用的
x = (ResultType)y
?
答案 1 :(得分:3)
当TSource
和TResult
都是引用类型时,这很简单。
如果其中一个或另一个是值类型,您希望它如何工作?值类型不能相互继承,因此不需要进行向上或向下转换。您可能希望在int
和double
之间进行数字转换,但您必须自己编写代码:.NET不会将它们视为类型转换。例如,DateTime
和string
之间的转换涉及更多的情报(什么格式?哪种文化?等)。
如果您只是处理参考类型,那么此方法可以是单行。如果你想处理值类型,那么你需要为各种组合编写特殊的案例代码。
编辑 Convert.ChangeType
在封装值类型之间的各种转换方面做得很合理。但是你提到你不想引入拳击:Convert.ChangeType
不是通用的,需要object
。
答案 2 :(得分:-1)
我认为您尝试解决的问题与您无法将一种类型的集合强制转换为另一种类型的集合的问题相同。 例如
类Obj1
{}
等级Obj2:Obj1
{}
列表与LT; OBJ2&GT; srcList = GetList();
列表与LT; OBJ1&GT; castedList =(List&lt; Obj2&gt;)srcList; //此行不会编译
我在实际查看CLR代码方面做得不多 然而,假设它像C ++一样,你在这里拥有的实际上是存储在集合中的不同值。换句话说,srcList将包含指向castedList中对象2接口的指针列表,您将拥有指向对象2内对象1的接口的指针。
为了解决这个问题,您需要让您的转换函数遍历集合中的每个项目。但是,为了能够遍历项目,列表必须实现某种枚举接口。因此枚举接口需要是对转换函数的约束。
因此答案是否定的。
但是,如果您准备实施此操作,并对您可能具有的类型进行限制:
静态类ListCast&lt; TSource,TResult,TItemType&gt;
其中TSource:IEnumerable&lt; TItemType&gt;
其中TResult:IList&lt; TItemType&gt;,new()
{
静态TResult Cast(TSource列表)
{
TResult castedList = newTResult();
foreach(列表中的TtemType项)
{
castedList.Add(TItemType)项);
}
return castedList;
}
}
答案 3 :(得分:-1)
你可以这样做:
public static TResult MyCast<TSource, TResult>(TSource item)
{
return (TResult)((object)item);
}
很想知道这可能是坏事。