2010-04-23 16 views
5

Czy w środowisku wykonawczym można utworzyć klasę z DataTable, w której nazwa ColumnName będzie własnością klasy dynamicznej?Tworzenie klas dynamicznych w języku C#

+0

Dlaczego? Co próbujesz zrobić? – SLaks

+0

Masz na myśli zdefiniować nową klasę lub dynamicznie ustawić istniejące właściwości klasy? – JustLoren

+0

Chcę utworzyć nową klasę o nazwach kolumn DataTable – Polaris

Odpowiedz

1

Tak (używając Reflection.Emit), ale to zły pomysł.
Co próbujesz zrobić?

+0

Mam RadGridView, który ma pewne problemy, gdy używam dataTable jako źródło dla niego. Ale kiedy używam List wszystko działa dobrze. Jakieś pomysły? – Polaris

+1

Powinieneś zapytać o to jako osobne pytanie. – SLaks

1

Czytając twoje komentarze, poddaję się twojej podłości. Po prostu użyj Generics: używając pól listy do wygenerowania obiektów. Kod jest dość prosta:

public class DynClass<T, P> 
    { 
     public DynClass() 
     { 
      _fields = new Dictionary<T, P>(); 
     } 

     private IDictionary<T, P> _fields; 

     public IDictionary<T, P> Fields 
     { 
      get { return _fields; } 
     } 

    } 

    public class TestGenericInstances 
    { 
     public TestGenericInstances() 
     { 
      Client cli = new Client("Ash", "99999999901"); 

      /* Here you can create any instances of the Class. 
      * Also DynClass<string, object> 
      * */ 
      DynClass<string, Client> gen = new DynClass<string, Client>(); 

      /* Add the fields 
      * */ 
      gen.Fields.Add("clientName", cli); 

      /* Add the objects to the List 
      * */ 
      List<object> lstDyn = new List<object>().Add(gen); 
     }   
    } 
+0

Za każdym razem, gdy mogę mieć różne kolumny z różnymi nazwami i typami. Czy możesz opowiedzieć mi o swoim wariancie lub pokazać mi spokój kodu? – Polaris

1

Jeśli masz C# 4 można skorzystać z nowych funkcji dynamiki i ExpandoObject. Możesz read a tutorial about it here.

+2

To naprawdę niesamowite, co jest możliwe przy użyciu tej technologii! – Erup

4

z C# 4, można to zrobić

dynamic foo = new ExpandoObject(); 

// mimic grabbing a column name at runtime and adding it as a property 
((IDictionary<string, object>)foo).Add("Name", "Apple"); 

Console.WriteLine(foo.Name); // writes Apple to screen 

Nie polecamy go ani nic, ale to pokazuje, że jest to możliwe.

+0

Świetne narzędzie, ale nie w moim przypadku. Używam frameworka 3.5 – Polaris

0

Zamierzam zaglądać do ExpandoObject, o którym była mowa (głosowałem za tym rozwiązaniem, ale wydaje mi się łatwiej), ale tak, jest to możliwe. Buduję klasę w jednym z moich projektów, w których narzędzie innej firmy wymaga, aby linia CSV została zdefiniowana jako klasa.

Można zbudować kod (ja wliczone \ r \ n tak, że mogę odczytać kodu wynikowego):

 string code = "using FileHelpers;\r\n\r\n"; 

     code += "[DelimitedRecord(\"" + delimiter + "\")]\r\n"; 
     code += "public class CustomCSVInputFile "; 
     code += "{ \r\n"; 

     foreach (string column in columnList) 
     { 
      code += " public string " + column.Replace(" ", "") + ";\r\n"; 
     } 
     code += "}\r\n"; 

     CompilerResults compilerResults = CompileScript(code); 

...

public static CompilerResults CompileScript(string source) 
    { 
     CompilerParameters parms = new CompilerParameters(); 
     FileHelperEngine engine; 

     parms.GenerateExecutable = false; 
     parms.GenerateInMemory = true; 
     parms.IncludeDebugInformation = false; 

     string path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase).Replace("file:\\", "").Trim(); 

     parms.ReferencedAssemblies.Add(Path.Combine(path, "FileHelpers.dll")); 

     CodeDomProvider compiler = CSharpCodeProvider.CreateProvider("CSharp"); 

     return compiler.CompileAssemblyFromSource(parms, source); 
    } 

... Jak wspomniałem , Gdybym musiał zrobić to jeszcze raz, to zbadałbym ExpandoObject, ale zdecydowanie możliwe jest stworzenie klasy z DataTable. Będziesz musiał przesłuchać nazwy kolumn, aby zbudować swoje pola; mój przykład miał listę nazw kolumn dostarczonych z "," rozdzielonego łańcucha.

Mój przykład pochodzi z bardzo konkretnego przypadku użycia, ale powinien wystarczyć, aby ExpandoObject nie działał dla Ciebie.

Powiązane problemy