将Flat文件转换为List,这是另一个类的属性

时间:2017-02-24 14:14:56

标签: c# file reflection deserialization flat

Rprof(interval = 0.0001)
f()
Rprof(NULL)
fprof <- summaryRprof()$by.self

Rprof(interval = 0.0001)
perceptron(as.matrix(irissubdf[1:2]), irissubdf$y, 1, 10) 
Rprof(NULL)
perprof <- summaryRprof()$by.self

fprof$Fun <- rownames(fprof)
perprof$Fun <- rownames(perprof)

Selftime <- merge(fprof, perprof,
                  all = TRUE,
                  by = 'Fun',
                  suffixes = c(".lapply",".for"))

sum(!is.na(Selftime$self.time.lapply))
sum(!is.na(Selftime$self.time.for))
Selftime[order(Selftime$self.time.lapply, decreasing = TRUE),
         c("Fun","self.time.lapply","self.time.for")]

Selftime[is.na(Selftime$self.time.for),]

我有一个平面文件,其中包含Dummy Response的制表符分隔数据。 我希望将其序列化为Request对象。 实现需求应该是通用的,因为在这种情况下我只需要用户传递T(请求)并从平面文件中识别要填充的正确子类型。

我在Code下面将它转换为Object。它如何仅适用于具有字符串类型的属性。

public class DummyResponse
{
    public int UpdatedRecords { get; set; }
    public string Id { get; set; }
    public bool Isvalid { get; set; }
}

public class Request
{
    public List<DummyResponse> Changes { get; set; }
    public string ReuestedBy { get; set; }

    public Request()
    {
        Changes = new List<DummyResponse>();
    }
}

使用示例:

interface ICollectionBuilder
{
    object Build(IList dictionaries);
}

internal class CollectionBuilder<T> : ICollectionBuilder where T : new()
{
    public object Build(IList dictionaries)
    {
        var dictConverter = new DictionaryConerter<T>();
        return dictionaries
            .OfType<IDictionary<string, object>>()
            .Select(dict => dictConverter.ConvertTyped(dict))
            .ToList();
    }
}

interface IDictionaryConverter
{
    object Convert(IDictionary<string, object> dict);
}

internal class DictionaryConerter<T> : IDictionaryConverter where T : new()
{
    public object Convert(IDictionary<string, object> dict)
    {
        return ConvertTyped(dict);
    }

    public T ConvertTyped(IDictionary<string, object> dict)
    {
        T t = new T();
        var properties = t.GetType().GetProperties();

        foreach (KeyValuePair<string, object> curr in dict)
        {
            if (String.IsNullOrEmpty(curr.Key)) continue;
            if (curr.Value == null) continue;

            Type valType = null;
            Type newType = null;
            PropertyInfo currProperty = null;
            foreach (PropertyInfo p in properties)
            {
                if (String.IsNullOrEmpty(p.Name)) continue;

                if (String.Compare(p.Name.ToLower(), curr.Key.ToLower()) == 0)
                {
                    valType = t.GetType().GetProperty(p.Name).PropertyType;
                    newType = Nullable.GetUnderlyingType(valType) ?? valType;
                    currProperty = p;
                    break;
                }
            }
            object newVal = curr.Value;

            var curDict = curr.Value as IDictionary<string, object>;
            var curList = curr.Value as IList;
            if (curDict != null && newType.GetConstructor(Type.EmptyTypes) != null)
            {
                newVal = ((IDictionaryConverter)Activator.CreateInstance(typeof(DictionaryConerter<>).MakeGenericType(newType))).Convert(curDict);
            }
            else if (
                curList != null &&
                curList.OfType<IDictionary<string, object>>().Any() &&
                newType.IsGenericType &&
                newType.GetGenericTypeDefinition() == typeof(List<>) &&
                newType.GetGenericArguments()[0].GetConstructor(Type.EmptyTypes) != null)
            {
                newVal = ((ICollectionBuilder)Activator.CreateInstance(typeof(CollectionBuilder<>).MakeGenericType(newType.GetGenericArguments()[0]))).Build(curList);
            }

            t.GetType().GetProperty(currProperty.Name).SetValue(t, newVal);
        }

        return t;
    }
}

这里的问题是它不适用于除字符串以外的任何其他类型。

1 个答案:

答案 0 :(得分:0)

我在设置值

时使用下面的代码修复了它
                propertyVal = Convert.ChangeType(propertyVal, targetType);
                propertyInfo.SetValue(inputObject, propertyVal, null);