繁体   English   中英

泛型将未知类型转换为另一个

[英]Generics casting an unknown type to another

我将我的问题改写为更具体,并针对实际关注的领域。

我有许多不同的类,它们是我的实体,但我没有那个类。 当我想将实体升级到新的实体时,我想将属性转移到称为相同的新实体上(并且我发现它们不区分大小写)。

我的问题很简单,但可能需要一个复杂的答案。

当我遇到一种与升级版不同的类型时,我需要将旧版转换为新版。 这两种类型都是未知的,因为那就是重点。 我可以通过任何两个我想要的类,它将很好地传递属性。

因此,如果我有两节课:

public class OldEntity
{
    public string Name {get;set;}
    public int SomeProperty {get;set;}
}

public class NewEntity
{
    public string Name {get;set;}
    public string SomeProperty {get;set;}
}

所以我需要找出SomeProperty的旧类型,然后将其转换为SomeProperty的新类型。

我以为可以做的事,希望有一种更通用的方法:

switch (typeof(SomeProperty.Value.GetType())
{
    case typeof(Int):
        return Int.Parse(OldSomeProperty.Value);
}

显然,这是非常原始的代码,但是您可以理解要点。

请有人给我一种更通用的方式来做,还有一件事情是我已经下载了AutoMapper,它没有被评论,所以如果有人可以告诉我它在哪里以及如何做到这一点,那也是一个很好的答案。

因此,我尝试过简单的解决方法,但不是很通用:

public static object ConvertSourceObjectDestinationObject(object source, object destination)
{
    // get the string representation of the source object
    var strRepresentation = source.ToString();
    // find out the destinations type
    var originalCode = AssemblyCode(destination.GetType().Assembly.ToString());

    // search for a match then convert the source object to the new destination objects type
    switch (originalCode)
    {
        case 0:
            return strRepresentation;
        case 1:
            return int.Parse(strRepresentation);
        case 2:
            return decimal.Parse(strRepresentation);
        case 3:
            return DateTime.Parse(strRepresentation);
        case 4:
            return byte.Parse(strRepresentation);
        case 5:
            return float.Parse(strRepresentation);
        case 6:
            return Guid.Parse(strRepresentation);
        default:
            return strRepresentation;
    }
}

public static int AssemblyCode(string assemblyString)
{
    if (assemblyString.Equals(typeof(string).Assembly.ToString()))
        return 0;

    if (assemblyString.Equals(typeof(int).Assembly.ToString()))
        return 1;

    if (assemblyString.Equals(typeof(decimal).Assembly.ToString()))
        return 2;

    if (assemblyString.Equals(typeof(DateTime).Assembly.ToString()))
        return 3;

    if (assemblyString.Equals(typeof(byte).Assembly.ToString()))
        return 4;

    if (assemblyString.Equals(typeof(float).Assembly.ToString()))
        return 5;

    if (assemblyString.Equals(typeof(Guid).Assembly.ToString()))
        return 6;

    return -1;
}

我做了一个新的函数,它使用TryParse而不是Parse来使其更安全,但是您的要点是。 我知道这不是很优雅,但是如果有人可以让我了解如何正确地将未知对象投射到其他未知对象,那就太好了。

泛型系统需要一些帮助,这有时会知道泛型是什么类型。 这是通过类型约束( ref )来解决的,它可能会对您的示例有所帮助。

如果知道要转换的泛型类型始终是某些基类,请使用where T:<base class name>约束。

如果强制转换异常是由于它无法识别未继承的类型之间的隐式强制转换,则反射可能是您唯一的选择。

您使用通用约束new

 public static void SetEntityValue<TEntity>(ref TEntity entityToTransform, PropertyHelper entityProperty) where TEntity: new

这将使您能够:

TEntity ent = new TEntity()

或(我认为这是您想要的)

使用相同的东西(通用约束),您可以告诉方法通用参数类型是从/派生的。

public static void SetEntityValue<TEntity>(ref TEntity entityToTransform, PropertyHelper entityProperty) where TEntity: x

这基本上意味着您可以告诉编译器泛型类型必须是什么(这意味着您在方法中进行的强制转换将很有意义并可以进行编译

如果您不知道类型将是什么,那么您可能会喜欢在对象上使用反射...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM