0

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

我有许多不同的类是我的实体,我不知道该类中的内容。当我想将实体升级到新实体时,我想将属性转移到称为相同的新实体(并且我发现它们不区分大小写)。

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

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

所以,如果我有两节课:

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 以使其更安全,但你明白了要点。我知道它并不优雅,但如果有人能告诉我如何正确地将未知物体投射到其他未知物体上,那就太好了。

4

2 回答 2

1

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

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

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

于 2013-01-05T18:36:58.210 回答
0

您使用通用约束 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

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

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

于 2013-01-05T17:37:40.450 回答