Methods with more than one Generic [closed]

2

There is a possibility to create a method using more than one type of generic , more or less like this.

    public static TResult ToEntityForType<TResult>(this DataRow row, TType type) where TType : Type
    {
        TResult entity = Activator.CreateInstance<TType>() as TResult;

        List<PropertyInfo> properties = entity.GetType().GetProperties().ToList();

        DataColumnCollection columnsTable = row.Table.Columns;

        for (int i = 0; i < columnsTable.Count; i++)
        {
            PropertyInfo prop = properties.Single(x => x.Name.ToUpper() == columnsTable[i].ColumnName.ToUpper());
            if (prop != null)
            {
                string result = Convert.ToString(row[i]);
                if (result.Trim() == String.Empty)
                    prop.SetValue(entity, null);
                else
                    prop.SetValue(entity, row[i]);
            }
        }
        return entity;
    }
    
asked by anonymous 15.06.2017 / 15:11

2 answers

2

I solved my question by returning an Object and using Type as parameter to be able to create the instance of my object.

    public static object ToEntityForType(this DataRow row, Type type)
    {
        EntityBase entity = Activator.CreateInstance(type) as EntityBase;

        List<PropertyInfo> properties = entity.GetType().GetProperties().ToList();

        DataColumnCollection columnsTable = row.Table.Columns;

        for (int i = 0; i < columnsTable.Count; i++)
        {
            PropertyInfo prop = properties.Single(x => x.Name.ToUpper() == columnsTable[i].ColumnName.ToUpper());
            if (prop != null)
            {
                string result = Convert.ToString(row[i]);
                if (result.Trim() == String.Empty)
                    prop.SetValue(entity, null);
                else
                    prop.SetValue(entity, row[i]);
            }
        }
        return entity;
    }
    
15.06.2017 / 15:49
2

This code will work better like this:

public static TResult ToEntityForType<TResult>(this DataRow row, Type type) {
    var entity = Activator.CreateInstance<type>() as TResult;
    var properties = entity.GetType().GetProperties().ToList();
    foreach (var item in row.Table.Columns) {
        if (properties.Single(x => String.Compare(x.Name, item.ColumnName, StringComparison.OrdinalIgnoreCase) == 0) != null) {
            prop.SetValue(entity, String.IsNullOrWhiteSpace(Convert.ToString(item)) ? null : item));
    }
    return entity;
}

I placed GitHub for future reference .

If I had a minimal, complete, and verifiable example I would show it working. I may have missed some detail.

In this case you do not need genetics in Type .

It has some other details that can be done much simpler and more correct, the original code would give error in several situations. This is not the best way, but it is an improvement.

Generics is a form of polymorphism. It should only be used if it is needed, if it can actually receive several different types. In case Type is only inherited by one type throughout .NET, if you did not inherit from it, you do not have to use generics , there is no polymorphism. Just use the direct type.

Putting object into place is not a solution, it's making a situation worse than getting it wrong. object only works this way because in the beginning C # had generics and was the only way to generalize something. But I repeat, in this case generalization is not necessary.

As the AP seems to be obsessed with generics I will make it very clear:

Only use generics where it really is needed, where it brings benefits . I study the subject more deeply before attempting to use it. TResult is required. I'm just not sure if it can be solved with it in this case.

I even have doubts if you need reflection, so there you need more context.

    
15.06.2017 / 15:51