Question about C #

I'm a little rusty on generics trying to do the following, but the compiler complains:

protected List<T> PopulateCollection(DataTable dt) where T: BusinessBase
{
    List<T> lst = new List<T>();
    foreach (DataRow dr in dt.Rows)
    {
        T t = new T(dr);
        lst.Add(t);
    }
    return lst;
}

So, as you can see, I'm trying to unload the contents of the table into an object (by passing the DataRow to the constructor), and then add the object to the collection. he complains that T is not the type or namespace that he knows about, and that I cannot use it in a declaration that is not generic.

Is it impossible?

+3
source share
6 answers

There are two big problems:

  • You cannot specify a constructor constraint that accepts a parameter
  • Your method is currently not general - it should be PopulateCollection<T>instead PopulateCollection.

T : BusinessBase, , , ( ) BusinessBase:

public abstract void PopulateFrom(DataRow dr);

T.

:

protected List<T> PopulateCollection(DataTable dt)
    where T: BusinessBase, new()
{
    List<T> lst = new List<T>();
    foreach (DataRow dr in dt.Rows)
    {
        T t = new T();
        t.PopulateFrom(dr);
        lst.Add(t);
    }
    return lst;
}

.NET 3.5, DataTableExtensions:

protected List<T> PopulateCollection<T>(DataTable dt)
    where T: BusinessBase, new()
{
    return dt.AsEnumerable().Select(dr => 
    { 
        T t = new T();
        t.PopulateFrom(dr);
    }.ToList();
}

( , .NET 3.5) :

static List<T> ToList<T>(this DataTable dt, Func<DataRow dr, T> selector)
    where T: BusinessBase
{
    return dt.AsEnumerable().Select(selector).ToList();
}

:

table.ToList(row => new Whatever(row));

, , DataRow. ( , ), , , "factory".

+21

, , , new() - , . , :

interface ISupportInitializeFromDataRow
{
    void InitializeFromDataRow(DataRow dataRow);
}

protected List<T> PopulateCollection<T>(DataTable dt) 
    where T : BusinessBase, ISupportInitializeFromDataRow, new()
{
    List<T> lst = new List<T>();
    foreach (DataRow dr in dt.Rows)
    {
        T t = new T();
        t.InitializeFromDataRow(dr);

        lst.Add(t);
    }
    return lst;
}

protected List<T> PopulateCollection<T>(DataTable dt, Func<DataRow, T> builder) 
    where T : BusinessBase
{
    List<T> lst = new List<T>();
    foreach (DataRow dr in dt.Rows)
    {
        T t = builder(dr);        
        lst.Add(t);
    }
    return lst;
}
+3

, new T, :

protected List<T> PopulateCollection<T>(DataTable dt) where T : BusinessBase, new()
...

DataRow , , BusinessBase

+2

:

protected List<T> PopulateCollection<T>(DataTable dt) where T: BusinessBase, new()
    {
        List<T> lst = new List<T>();
        foreach (DataRow dr in dt.Rows)
        {
            T t = new T();
            t.DataRow = dr;
            lst.Add(t);
        }
        return lst;
    }
+2
where T: BusinessBase

new() ,

0

. . , , . . , .

 public class Book<APClass> : Book where APClass : APBase
        private DataTable Table ; // data
        public override IEnumerator GetEnumerator()
        {                        
            for (position = 0;  position < Table.Rows.Count;  position++)           
                 yield return APBase.NewFromRow<APClass>(Table.Rows[position], this.IsOffline);
        }
   ...


  public class APBase ...
  {
    ...
    internal static T NewFromRow<T>(DataRow dr, bool offline) where T : APBase
        {

            Type t = typeof(T);
            ConstructorInfo ci;

            if (!ciDict.ContainsKey(t))
            {
                ci = t.GetConstructor(new Type[1] { typeof(DataRow) });
                ciDict.Add(t, ci);
            }
            else ci = ciDict[t];

            T result = (T)ci.Invoke(new Object[] { dr });

            if (offline)
                result.drCache = dr;    

            return result;
        }

, tablerow.

0

Source: https://habr.com/ru/post/1706945/


All Articles