所以这是我的情况。我有2个类,TmdbTvShow和TvShow。
TmdbTvShow是一个充满了我从外部来源获得的数据的类。现在我想创建一种映射器来将它映射到我自己的类TvShow。
Class TvShow:
[MovieMap("TmdbTvShow")]
public class TvShow
{
public int ID { get; set; }
[MovieMapProperty("ID")]
public int TmdbID { get; set; }
[MovieMapProperty("Name")]
public string Name { get; set; }
[MovieMapProperty("OriginalName")]
public string OriginalName { get; set; }
[MovieMapProperty("Overview")]
public string Summary { get; set; }
[MovieMapProperty("FirstAirDate")]
public DateTime FirstAirDate { get; set; }
[MovieMapProperty("LastAirDate")]
public DateTime LastAirDate { get; set; }
[MovieMapProperty("Genres")]
public IEnumerable<Genre> Genres { get; set; }
[MovieMapProperty("InProduction")]
public bool Running { get; set; }
}
Mapper类:
public class MovieMapper
{
public MovieMapper()
{
}
public T Map<T>(object input) where T : new()
{
T obj = new T();
MovieMapAttribute[] classAttributes = (MovieMapAttribute[])obj.GetType().GetCustomAttributes(typeof(MovieMapAttribute), false);
if (classAttributes != null && classAttributes[0].ClassName.Equals(input.GetType().Name))
{
Dictionary<string, MovieMapPropertyAttribute> propAtts = new Dictionary<string, MovieMapPropertyAttribute>();
foreach (PropertyInfo prop in obj.GetType().GetProperties())
{
MovieMapPropertyAttribute[] mma = (MovieMapPropertyAttribute[])prop.GetCustomAttributes(typeof(MovieMapPropertyAttribute), false);
// Attribute found
if (mma.Length > 0)
{
// Get attribute
MovieMapPropertyAttribute mmp = mma[0];
// Get value
var value = input.GetType().GetProperty(mmp.PropertyName).GetValue(input, null);
// Is property a dateTime
if (typeof(DateTime).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, Convert.ToDateTime(value), null);
}
else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string))
{
}
else if (typeof(Boolean).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, Convert.ToBoolean(value), null);
}
else
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, value, null);
}
}
}
}
else
throw new Exception("Wrong object");
return obj;
}
}
所以我的工作就像int,string,booleans&amp; DateTime将映射到我的对象。
但是你可以看到我的TvShow类中有一个IEnumerable。这是这个TvShow的流派集合。
我对如何制作2个IEnumerables彼此映射有点困惑。 如果我像字符串一样,我会收到此错误:
a object of type System.Collections.Generic.List can not be converted to the type System.Collections.Generic.IEnumerable
也许有人可以把我放在正确的方向来处理这个问题?
干杯
答案 0 :(得分:0)
您可以创建一个IEnumerable
的列表,将项目添加到该列表中,然后将其分配给该属性。
如果您需要将对象从TmdbGenre
转换为Genre
,则可以递归调用Map
,但您可能需要一个接受类型参数的Map
版本。
public object Map(Type type, object input);
var result = value.Select(x => Map(prop.GetType().GetGenericArguments()[0], x));
prop.SetValue(obj, result);
答案 1 :(得分:0)
好的,经过大量的努力,我已经明白了。
这是我的解决方案:
public T Map<T>(object input) where T : new()
{
T obj = new T();
MovieMapAttribute[] classAttributes = (MovieMapAttribute[])obj.GetType().GetCustomAttributes(typeof(MovieMapAttribute), false);
if (classAttributes != null && classAttributes[0].ClassName.Equals(input.GetType().Name))
{
Dictionary<string, MovieMapPropertyAttribute> propAtts = new Dictionary<string, MovieMapPropertyAttribute>();
foreach (PropertyInfo prop in obj.GetType().GetProperties())
{
MovieMapPropertyAttribute[] mma = (MovieMapPropertyAttribute[])prop.GetCustomAttributes(typeof(MovieMapPropertyAttribute), false);
// Attribute found
if (mma.Length > 0)
{
// Get attribute
MovieMapPropertyAttribute mmp = mma[0];
if (input.GetType().GetProperty(mmp.PropertyName) != null)
{
// Get value
var value = input.GetType().GetProperty(mmp.PropertyName).GetValue(input, null);
// Is property a dateTime
if (typeof(DateTime).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, Convert.ToDateTime(value), null);
}
else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string) && prop.PropertyType != typeof(string[]))
{
Type type = prop.PropertyType.GetGenericArguments()[0];
var list = (IEnumerable)value;
dynamic values = Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
foreach (object ob in list)
{
object tempObj = Activator.CreateInstance(type);
tempObj = Map(ob, tempObj);
values.Add((dynamic)tempObj);
}
obj.GetType().GetProperty(prop.Name).SetValue(obj, values, null);
}
else if (typeof(Boolean).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, Convert.ToBoolean(value), null);
}
else if (typeof(int).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, Convert.ToInt32(value), null);
}
else if (typeof(float).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, float.Parse(value.ToString(), System.Globalization.CultureInfo.InvariantCulture.NumberFormat), null);
}
else
{
// Set value to object
obj.GetType().GetProperty(prop.Name).SetValue(obj, value, null);
}
}
}
}
}
else
throw new Exception("Wrong object");
return obj;
}
private object Map(object input, object output)
{
MovieMapAttribute[] classAttributes = (MovieMapAttribute[])output.GetType().GetCustomAttributes(typeof(MovieMapAttribute), false);
if (classAttributes != null && classAttributes[0].ClassName.Equals(input.GetType().Name))
{
foreach (PropertyInfo prop in output.GetType().GetProperties())
{
MovieMapPropertyAttribute[] mma = (MovieMapPropertyAttribute[])prop.GetCustomAttributes(typeof(MovieMapPropertyAttribute), false);
// Attribute found
if (mma.Length > 0)
{
// Get attribute
MovieMapPropertyAttribute mmp = mma[0];
if (input.GetType().GetProperty(mmp.PropertyName) != null)
{
var value = input.GetType().GetProperty(mmp.PropertyName).GetValue(input, null);
// Is property a dateTime
if (typeof(DateTime).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
output.GetType().GetProperty(prop.Name).SetValue(output, Convert.ToDateTime(value), null);
}
else if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string) && prop.PropertyType != typeof(string[]))
{
Type type = prop.PropertyType.GetGenericArguments()[0];
var list = (IEnumerable)value;
dynamic values = Activator.CreateInstance(typeof(List<>).MakeGenericType(type));
foreach (object ob in list)
{
object tempObj = Activator.CreateInstance(type);
tempObj = Map(ob, tempObj);
values.Add((dynamic)tempObj);
}
output.GetType().GetProperty(prop.Name).SetValue(output, values, null);
}
else if (typeof(Boolean).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
output.GetType().GetProperty(prop.Name).SetValue(output, Convert.ToBoolean(value), null);
}
else if (typeof(int).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
output.GetType().GetProperty(prop.Name).SetValue(output, Convert.ToInt32(value), null);
}
else if (typeof(float).IsAssignableFrom(prop.PropertyType))
{
// Set value to object
output.GetType().GetProperty(prop.Name).SetValue(output, float.Parse(value.ToString(), System.Globalization.CultureInfo.InvariantCulture.NumberFormat), null);
}
else
{
// Set value to object
output.GetType().GetProperty(prop.Name).SetValue(output, value, null);
}
}
}
}
}
else
throw new Exception("Wrong object");
return output;
}
它工作正常,它在ienumerables等中映射ienumerables。
谢谢Ned指出我正确的方向,会把你当作一个好答案!