>

제네릭에 대해 방금 배웠으며 클래스에서 데이터 테이블을 동적으로 빌드하는 데 사용할 수 있는지 궁금합니다.

또는 여기에 요점이 없을 수도 있습니다. 여기 내 코드가 있는데, 내가하려고하는 것은 기존 클래스에서 데이터 테이블을 만들고 채우는 것입니다. 그러나 나는 나의 사고 과정에 갇혀있다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
namespace Generics
{
    public class Dog
    {
        public string Breed { get; set; }
        public string Name { get; set; }
        public int legs { get; set; }
        public bool tail { get; set; }
    }
    class Program
    {
        public static DataTable CreateDataTable(Type animaltype)
        {
            DataTable return_Datatable = new DataTable();
            foreach (PropertyInfo info in animaltype.GetProperties())
            {
                return_Datatable.Columns.Add(new DataColumn(info.Name, info.PropertyType));
            }
            return return_Datatable;
        }
        static void Main(string[] args)
        {
            Dog Killer = new Dog();
            Killer.Breed = "Maltese Poodle";
            Killer.legs = 3;
            Killer.tail = false;
            Killer.Name = "Killer";
            DataTable dogTable = new DataTable();
            dogTable = CreateDataTable(Dog);
//How do I continue from here?

        }      
    }
}   

지금 DataTable 에서  오류를 지적하십시오. 또한 리플렉션 및 제네릭을 처음 사용하는 경우 실제로 Killer 클래스로 데이터를 채우려면 어떻게해야합니까?


  • 답변 # 1

    이전의 모든 답변을 바탕으로 모든 컬렉션에서 DataTable을 만드는 버전은 다음과 같습니다.

    public static DataTable CreateDataTable<T>(IEnumerable<T> list)
    {
        Type type = typeof(T);
        var properties = type.GetProperties();      
        DataTable dataTable = new DataTable();
        foreach (PropertyInfo info in properties)
        {
            dataTable.Columns.Add(new DataColumn(info.Name, Nullable.GetUnderlyingType(info.PropertyType) ?? info.PropertyType));
        }
        foreach (T entity in list)
        {
            object[] values = new object[properties.Length];
            for (int i = 0; i < properties.Length; i++)
            {
                values[i] = properties[i].GetValue(entity);
            }
            dataTable.Rows.Add(values);
        }
        return dataTable;
    }
    
    

  • 답변 # 2

    내가 가장 좋아하는 수제 기능. 동시에 작성하고 채 웁니다. 물건을 던지십시오.

    public static DataTable ObjectToData(object o)
     {
        DataTable dt = new DataTable("OutputData");
        DataRow dr = dt.NewRow();
        dt.Rows.Add(dr);
        o.GetType().GetProperties().ToList().ForEach(f =>
        {
            try
            {
                f.GetValue(o, null);
                dt.Columns.Add(f.Name, f.PropertyType);
                dt.Rows[0][f.Name] = f.GetValue(o, null);
            }
            catch { }
        });
        return dt;
     }
    
    

  • 답변 # 3

    확장 함수이기도 한 David의 답은보다 간결한 버전입니다. Github의 C # 프로젝트에 코드를 게시했습니다.

    public static class Extensions
    {
        public static DataTable ToDataTable<T>(this IEnumerable<T> self)
        {
            var properties = typeof(T).GetProperties();
            var dataTable = new DataTable();
            foreach (var info in properties)
                dataTable.Columns.Add(info.Name, Nullable.GetUnderlyingType(info.PropertyType) 
                   ?? info.PropertyType);
            foreach (var entity in self)
                dataTable.Rows.Add(properties.Select(p => p.GetValue(entity)).ToArray());
            return dataTable;
        }     
    }
    
    

    DataTable을 CSV로 작성하는 코드와 함께 이것이 잘 작동한다는 것을 알았습니다.

  • 답변 # 4

    다음을 변경하여 오류를 해결할 수 있습니다.

    dogTable = CreateDataTable(Dog);
    
    

    이것에 대해 :

    dogTable = CreateDataTable(typeof(Dog));
    
    

    그러나 당신이하려는 일에주의해야 할 몇 가지주의 사항이 있습니다. 첫째, DataTable  복잡한 유형을 저장할 수 없으므로 Dog   Cat 의 인스턴스가 있습니다  그것에, 당신은 그것을 열로 추가 할 수 없습니다. 이 경우 원하는 작업은 사용자에게 달려 있지만 명심하십시오.

    둘째, 나는 당신이 DataTable 를 사용할 때만 권장합니다  소비하는 데이터에 대해아무것도아는 코드를 작성할 때입니다. 이에 대한 유효한 사용 사례가 있습니다 (예 : 사용자 중심 데이터 마이닝 도구). 이미 Dog 에 데이터가있는 경우  사용하세요.

    또 다른 작은 음식, 이것 :

    DataTable dogTable = new DataTable();
    dogTable = CreateDataTable(Dog);
    
    

    이것으로 요약 될 수 있습니다 :

    DataTable dogTable = CreateDataTable(Dog);
    
    

  • 답변 # 5

    데이터 시간 필드의 시간대 문제를 수정 한 약간 수정 된 코드는 다음과 같습니다.

       public static DataTable ToDataTable<T>(this IList<T> data)
        {
            PropertyDescriptorCollection props =
                TypeDescriptor.GetProperties(typeof(T));
            DataTable table = new DataTable();
            for (int i = 0; i < props.Count; i++)
            {
                PropertyDescriptor prop = props[i];
                table.Columns.Add(prop.Name, prop.PropertyType);
            }
            object[] values = new object[props.Count];
            foreach (T item in data)
            {
                for (int i = 0; i < values.Length; i++)
                {
                    if (props[i].PropertyType == typeof(DateTime))
                    {
                        DateTime currDT = (DateTime)props[i].GetValue(item);
                        values[i] = currDT.ToUniversalTime();
                    }
                    else
                    {
                        values[i] = props[i].GetValue(item);
                    }
                }
                table.Rows.Add(values);
            }
            return table;
        }
    
    

관련 자료

  • 이전 SQL Server 용 데이터 생성기?
  • 다음 android - ListView에서 끝없는 스크롤 구현