Skip to content

Commit

Permalink
优化CreateInstance创建对象,支持列表和字典
Browse files Browse the repository at this point in the history
  • Loading branch information
nnhy committed Mar 28, 2024
1 parent 318491e commit 6da909d
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 36 deletions.
65 changes: 32 additions & 33 deletions NewLife.Core/Data/TimePoint.cs
Original file line number Diff line number Diff line change
@@ -1,42 +1,41 @@
using System;

namespace NewLife.Data
namespace NewLife.Data;

/// <summary>
/// 时序点,用于时序数据计算
/// </summary>
public struct TimePoint
{
/// <summary>
/// 时序点,用于时序数据计算
/// 时间
/// </summary>
public struct TimePoint
{
/// <summary>
/// 时间
/// </summary>
public Int64 Time;
public Int64 Time;

/// <summary>
/// 数值
/// </summary>
public Double Value;
/// <summary>
/// 数值
/// </summary>
public Double Value;

/// <summary>
/// 已重载
/// </summary>
/// <returns></returns>
public override String ToString() => $"({Time}, {Value})";
}
/// <summary>
/// 已重载
/// </summary>
/// <returns></returns>
public override String ToString() => $"({Time}, {Value})";
}

///// <summary>
///// 时序点,用于时序数据计算
///// </summary>
//public struct LongTimePoint
//{
// /// <summary>
// /// 时间
// /// </summary>
// public Int64 Time;
///// <summary>
///// 时序点,用于时序数据计算
///// </summary>
//public struct LongTimePoint
//{
// /// <summary>
// /// 时间
// /// </summary>
// public Int64 Time;

// /// <summary>
// /// 数值
// /// </summary>
// public Double Value;
//}
}
// /// <summary>
// /// 数值
// /// </summary>
// public Double Value;
//}
37 changes: 34 additions & 3 deletions NewLife.Core/Reflection/IReflect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Web.Script.Serialization;
using System.Xml.Serialization;
using NewLife.Data;
using static System.Collections.Specialized.BitVector32;

namespace NewLife.Reflection;

Expand Down Expand Up @@ -424,10 +425,40 @@ private IList<PropertyInfo> GetProperties2(Type type, Boolean baseFirst)
{
try
{
var code = type.GetTypeCode();

// 列表
if (code == TypeCode.Object && (type.As<IList>() || type.As(typeof(IList<>))))
{
var type2 = type;
if (type2.IsInterface)
{
if (type2.IsGenericType)
type2 = typeof(List<>).MakeGenericType(type2.GetGenericArguments());
else if (type2 == typeof(IList))
type2 = typeof(List<Object>);
}
return Activator.CreateInstance(type2);
}

// 字典
if (code == TypeCode.Object && (type.As<IDictionary>() || type.As(typeof(IDictionary<,>))))
{
var type2 = type;
if (type2.IsInterface)
{
if (type2.IsGenericType)
type2 = typeof(Dictionary<,>).MakeGenericType(type2.GetGenericArguments());
else if (type2 == typeof(IDictionary))
type2 = typeof(Dictionary<Object, Object>);
}
return Activator.CreateInstance(type2);
}

if (parameters == null || parameters.Length == 0)
{
// 基元类型
return type.GetTypeCode() switch
return code switch
{
//TypeCode.Empty or TypeCode.DBNull => null,
TypeCode.Boolean => false,
Expand All @@ -453,7 +484,6 @@ private IList<PropertyInfo> GetProperties2(Type type, Boolean baseFirst)
}
catch (Exception ex)
{
//throw new Exception("创建对象失败 type={0} parameters={1}".F(type.FullName, parameters.Join()), ex);
throw new Exception($"Fail to create object type={type.FullName} parameters={parameters?.Join()} {ex.GetTrue()?.Message}", ex);
}
}
Expand Down Expand Up @@ -629,7 +659,8 @@ public virtual void Copy(Object target, IDictionary<String, Object?> source, Boo
// 如果实现了IEnumerable<>接口,那么取泛型参数
foreach (var item in type.GetInterfaces())
{
if (item.IsGenericType && item.GetGenericTypeDefinition() == typeof(IEnumerable<>)) return item.GetGenericArguments()[0];
if (item.IsGenericType && item.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return item.GetGenericArguments()[0];
}
//// 通过索引器猜测元素类型
//var pi = type.GetProperty("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
Expand Down
67 changes: 67 additions & 0 deletions XUnitTest.Core/Reflection/ReflectTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using NewLife.Data;
using NewLife.Reflection;
using Xunit;

Expand Down Expand Up @@ -82,4 +83,70 @@ public void AsDictionaryTest()
Assert.True(type.As(typeof(IDictionary<Int32, String>)));
Assert.True(type.As(typeof(IDictionary<,>)));
}

[Fact]
public void CreateInstance()
{
var type = typeof(PageParameter);
var obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<PageParameter>(obj);

type = typeof(DbTable);
obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<DbTable>(obj);
}

//[Fact]
//public void CreateInstanceForArray()
//{
// var type = typeof(Int32[]);
// var obj = type.CreateInstance();
// Assert.NotNull(obj);
// Assert.IsType<Int32[]>(obj);

// type = typeof(PageParameter[]);
// obj = type.CreateInstance();
// Assert.NotNull(obj);
// Assert.IsType<PageParameter[]>(obj);
//}

[Fact]
public void CreateInstanceForList()
{
var type = typeof(List<Int32>);
var obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<List<Int32>>(obj);

type = typeof(IList<PageParameter>);
obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<List<PageParameter>>(obj);

type = typeof(IList);
obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<List<Object>>(obj);
}

[Fact]
public void CreateInstanceForDictionary()
{
var type = typeof(Dictionary<Int32, String>);
var obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<Dictionary<Int32, String>>(obj);

type = typeof(IDictionary<String, PageParameter>);
obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<Dictionary<String, PageParameter>>(obj);

type = typeof(IDictionary);
obj = type.CreateInstance();
Assert.NotNull(obj);
Assert.IsType<Dictionary<Object, Object>>(obj);
}
}
28 changes: 28 additions & 0 deletions XUnitTest.Core/Serialization/JsonTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,4 +470,32 @@ partial class LineBill
public Double Volume { get; set; }
#endregion
}

[Fact]
public void Convert()
{
var infos = new List<LineBill>
{
new() { Id = 1, FirstId = "1", LastId = "2", Weight = 1, Volume = 1 },
new() { Id = 2, FirstId = "2", LastId = "3", Weight = 2, Volume = 2 },
new() { Id = 3, FirstId = "3", LastId = "4", Weight = 3, Volume = 3 }
};
var p = new
{
infos,
};
var json = p.ToJson();

var dic = JsonParser.Decode(json);
var data = dic["infos"];
Assert.NotNull(data);

var fs = JsonHelper.Convert<IList<LineBill>>(data);
Assert.NotNull(fs);
Assert.Equal(infos.Count, fs.Count);

var arr = JsonHelper.Convert<LineBill[]>(data);
Assert.NotNull(arr);
Assert.Equal(infos.Count, arr.Length);
}
}

0 comments on commit 6da909d

Please sign in to comment.