如何使用值类型约束在通用声明的类型之间进行复制

时间:2022-02-02 16:27:25

I have a generic method that copies values between value types. The following approaches give a design time error, even with the struct constraint. Any idea how I can copy or cast between the values?

我有一个在值类型之间复制值的通用方法。即使使用struct约束,以下方法也会产生设计时错误。知道如何在值之间复制或转换吗?

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc SourceObject) 
    where Tsrc : struct
    where Ttgt : struct
{
    //Error:cannot implictly convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = SourceObject; 

    //Error:Cannot convert type 'Tsrc' to 'Ttgt'
    Ttgt returnObject = (Ttgt)SourceObject; 

    return returnObject;
}

5 个解决方案

#1


3  

Given that there is a registered type converter for the types that you're trying to convert between a little reflection magic could do the trick:

鉴于有一个注册类型的转换器,你试图在一点点反射之间转换魔术可以做到这一点:

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc sourceObject) 
    where Tsrc:struct where  Ttgt:struct    
{    
    Type targetType = typeof(Ttgt);
    TypeConverter tc = TypeDescriptor.GetConverter(targetType);
    Ttgt returnObject = (Ttgt)tc.ConvertTo(sourceObject, targetType);
    return returnObject;    
}

But out of the box it would be of very limited use since there is no converter between bool and int for example. What problem are you trying to solve?

但开箱即用它的用途非常有限,因为例如bool和int之间没有转换器。你想解决什么问题?

I also discovered another question with some crazy conversion code in it.

我还发现了另一个带有一些疯狂转换代码的问题。

Edit: Your comment makes it clear that you are trying to perform object to object mapping between domain objects and some kind of view/contract model. Have you looked at AutoMapper?

编辑:您的注释清楚地表明您正在尝试在域对象和某种视图/合同模型之间执行对象到对象的映射。你看过AutoMapper了吗?

#2


1  

//Error:Cannot convert type 'Tsrc' to 'Ttgt'

//错误:无法将类型'Tsrc'转换为'Ttgt'

You cannot convert between arbitrary types, unless there is an accessible conversion operator.

除非有可访问的转换运算符,否则无法在任意类型之间进行转换。

#3


1  

The two are defined as different types. Even though they are both structs, they are not the same types.

这两个被定义为不同的类型。尽管它们都是结构,但它们的类型并不相同。

Define both souce and target as the same type:

将souce和target定义为相同的类型:

private T MyMethod<T>(T source, T target)
{

#4


0  

This is "By Design." You are attempting to cast between two unrelated value types. This will never succeed and therefore it is flagged as an error.

这是“按设计”。您试图在两个不相关的值类型之间进行转换。这将永远不会成功,因此它被标记为错误。

This will be true of all value typse because they are implicitly sealed. In order for a cast between TSrc -> Ttgt to succeed, there must be a class hierarchy relationship between the two types. This cannot be because all value types are sealed hence there is no way one can derive from the other.

所有价值的例子都是如此,因为它们是隐含密封的。为了使TSrc - > Ttgt之间的转换成功,两种类型之间必须存在类层次关系。这不可能是因为所有的值类型都是密封的,因此没有办法可以从另一个中派生出来。

The only way this could succeed is if one had a custom conversion operator between the types. This may be the case. However when dealing with generic types, custom conversion operators will not be processed.

这种方法成功的唯一方法是在类型之间有一个自定义转换运算符。情况可能如此。但是,在处理泛型类型时,不会处理自定义转换运算符。

#5


0  

The Convert class exists for this exact purpose.

Convert类存在于此确切目的。

private Ttgt MyMethod<Tsrc, Ttgt>(Tsrc SourceObject)
    where Tsrc : struct
    where Ttgt : struct
{
    return (Ttgt) Convert.ChangeType(SourceObject, typeof(Ttgt));
}

Also note that you could do this:

另请注意,您可以这样做:

    return (Ttgt) (object) SourceObject;

#1


3  

Given that there is a registered type converter for the types that you're trying to convert between a little reflection magic could do the trick:

鉴于有一个注册类型的转换器,你试图在一点点反射之间转换魔术可以做到这一点:

private Ttgt MyMethod<Tsrc,Ttgt>(Tsrc sourceObject) 
    where Tsrc:struct where  Ttgt:struct    
{    
    Type targetType = typeof(Ttgt);
    TypeConverter tc = TypeDescriptor.GetConverter(targetType);
    Ttgt returnObject = (Ttgt)tc.ConvertTo(sourceObject, targetType);
    return returnObject;    
}

But out of the box it would be of very limited use since there is no converter between bool and int for example. What problem are you trying to solve?

但开箱即用它的用途非常有限,因为例如bool和int之间没有转换器。你想解决什么问题?

I also discovered another question with some crazy conversion code in it.

我还发现了另一个带有一些疯狂转换代码的问题。

Edit: Your comment makes it clear that you are trying to perform object to object mapping between domain objects and some kind of view/contract model. Have you looked at AutoMapper?

编辑:您的注释清楚地表明您正在尝试在域对象和某种视图/合同模型之间执行对象到对象的映射。你看过AutoMapper了吗?

#2


1  

//Error:Cannot convert type 'Tsrc' to 'Ttgt'

//错误:无法将类型'Tsrc'转换为'Ttgt'

You cannot convert between arbitrary types, unless there is an accessible conversion operator.

除非有可访问的转换运算符,否则无法在任意类型之间进行转换。

#3


1  

The two are defined as different types. Even though they are both structs, they are not the same types.

这两个被定义为不同的类型。尽管它们都是结构,但它们的类型并不相同。

Define both souce and target as the same type:

将souce和target定义为相同的类型:

private T MyMethod<T>(T source, T target)
{

#4


0  

This is "By Design." You are attempting to cast between two unrelated value types. This will never succeed and therefore it is flagged as an error.

这是“按设计”。您试图在两个不相关的值类型之间进行转换。这将永远不会成功,因此它被标记为错误。

This will be true of all value typse because they are implicitly sealed. In order for a cast between TSrc -> Ttgt to succeed, there must be a class hierarchy relationship between the two types. This cannot be because all value types are sealed hence there is no way one can derive from the other.

所有价值的例子都是如此,因为它们是隐含密封的。为了使TSrc - > Ttgt之间的转换成功,两种类型之间必须存在类层次关系。这不可能是因为所有的值类型都是密封的,因此没有办法可以从另一个中派生出来。

The only way this could succeed is if one had a custom conversion operator between the types. This may be the case. However when dealing with generic types, custom conversion operators will not be processed.

这种方法成功的唯一方法是在类型之间有一个自定义转换运算符。情况可能如此。但是,在处理泛型类型时,不会处理自定义转换运算符。

#5


0  

The Convert class exists for this exact purpose.

Convert类存在于此确切目的。

private Ttgt MyMethod<Tsrc, Ttgt>(Tsrc SourceObject)
    where Tsrc : struct
    where Ttgt : struct
{
    return (Ttgt) Convert.ChangeType(SourceObject, typeof(Ttgt));
}

Also note that you could do this:

另请注意,您可以这样做:

    return (Ttgt) (object) SourceObject;