public static ICollection<T> CreateData<T>(this ICollection<T> obj, int size) { obj = new Collection<T>(); for (int i = 1; i <= size; i++) { T data = (T)Activator.CreateInstance(typeof(T)); var propertys = data.GetType().GetProperties(); foreach (var type in propertys) { if (type.CanWrite && type.PropertyType == typeof(int) || type.PropertyType == typeof(int?)) { type.SetValue(data, i); } if (type.CanWrite && type.PropertyType == typeof(long) || type.PropertyType == typeof(long?)) { type.SetValue(data, Convert.ToInt64(i)); } if (type.CanWrite && type.PropertyType == typeof(bool) || type.PropertyType == typeof(bool?)) { type.SetValue(data, true); } if (type.CanWrite && type.PropertyType == typeof(DateTime) || type.PropertyType == typeof(DateTime?)) { type.SetValue(data, DateTime.Now); } if (type.CanWrite && type.PropertyType == typeof(string)) { string value = "test" + type.Name + i; type.SetValue(data, value); } } obj.Add(data); } return obj; }
在这个方法中,我想要实现自动生成测试数据,可是,每有一个新返回值我就要复制一个一模一样的改改里面的返回参数。可是核心的东西都是一样的,请问有没有什么办法优化一下子呢?
private static T Data<T>(int i) { T data = (T)Activator.CreateInstance(typeof(T)); var propertys = data.GetType().GetProperties(); foreach (var type in propertys) { if (!type.CanWrite) { continue; } if (type.PropertyType == typeof(int) || type.PropertyType == typeof(int?)) { type.SetValue(data, i); } else if (type.PropertyType == typeof(long) || type.PropertyType == typeof(long?)) { type.SetValue(data, Convert.ToInt64(i)); } else if (type.PropertyType == typeof(bool) || type.PropertyType == typeof(bool?)) { type.SetValue(data, true); } else if (type.PropertyType == typeof(DateTime) || type.PropertyType == typeof(DateTime?)) { type.SetValue(data, DateTime.Now); } else if (type.PropertyType == typeof(string)) { string value = "test" + type.Name + i; type.SetValue(data, value); } } return data; }
我把方法改成了这样,这样的话调用方法只需要加一个方法就好了
public static ICollection<T> CreateData<T>(this ICollection<T> obj, int size) { obj = new Collection<T>(); for (int i = 1; i <= size; i++) { var data = Data<T>(i); obj.Add(data); } return obj; }
感谢楼上给的思路
你可以把这些type对应的set提取为一些规则,然后注册进入
最后直接从这个规则集合里面抽就可以了。
呃。。。可以举个粒子么。。。
@临冰听雪丶:
class Rules
{
public Rules RegisterRule<T>(Func<int,object> seqFunc)
{
//...add to the dictionary.
}
public Func<int,object> GetRule<T>()
{
//...get from dictionary
}
}
其中的Func<int,object>就是你对应的给property做set提供的dummy数据方法,前面那个int就是你for循环中的i(你需要用这个i生成不同的数据)
比如针对一个PropertyType为string的property,那么你那里做set的时候就是从Rules中获取
var func=xxxRules.Get<string>();
property.SetValue(objectInstance,func(i));
你对应的rule的委托对应的代码就是
i=>string.Format("dummy {0}",i);
通过这种方式你可以构建一个完全不需要更改的核心功能以及根据需求随意扩充的规则,当然你可以继续做下扩充,比如做配置化,这里就不再细化了。
@Daniel Cai: 不好意思,我不是很懂Func的用法,还是有些不太明白。。。
@Daniel Cai: 不知道该怎么下手。。刚才搜了下,网上说Func<int, object>,int是参数,object是返回值,可是方法里面该怎么写呢。。