2013-01-05 57 views
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而不是解析,使之更加安全的,但你得到的要点。它不是我所知道的优雅,但是如果有人能够用我的方式将未知物体投射到其他未知物体上,那将会很棒。

+0

我不明白你的问题。 'GetValue'和'SetValue'在'object'上操作,那么为什么你需要投射?如果不是使用带'x'和'y'的抽象例子,而是显示特定的行,导致您的方法出现问题,这可能会有所帮助。 –

+0

该方法出错了。我只传递对象,然后通过关于投射的错误! –

+0

对于光顾的语气我感到抱歉。我检查了你的个人资料,你绝对正确。 –

回答

1

通用系统需要一些帮助,知道什么类型的,有时,这与类型约束(ref)照顾的仿制药,这可以帮助你与你的榜样。

如果您知道您想要投射的泛型类型始终是某个基类,请使用where T:<base class name>约束。

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

0

您使用通用约束新

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 

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

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

+0

我没有试图实例化对象,我想将其属性值转换为另一个对象属性值! –

+0

我想我会使用反射。 –

+0

阅读你的其他评论,你可以使泛型方法只接受从特定接口派生的类型(它具有所有需要和共享的属性访问器)并添加该接口的通用约束@ No1_Melman –