2014-09-09 4 views
0

Не могу понять, почему мой fieldType не квалифицирован как общий список. Я попытался использовать предложенное ниже решение, чтобы получить общий тип списка. Но когда я достиг fieldType.IsGenericType == false, я был очень удивлен, и я не понимаю, что происходит.Почему список отражений <T> не является общим?

Моя цель - использовать мой метод CreateTable() для каждого поля в моем контексте. В моем контексте должны быть только поля «Список».

Это информация, которую я нашел в моем объекте:

FieldType = {Name = "List`1" FullName = 
"System.Collections.Generic.List`1[[WebApplication1.Models.Movie, WebApplication1, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"} 

Ссылка: C# generic list <T> how to get the type of T?

Мой пример кода:

public class MediaContext 
{ 
    public List<Movie> Movies { get; set; } 
    public List<Subtitle> Subtitles { get; set; } 

    public MediaContext() 
    { 
     this.Movies = new List<Movie>(); 
     this.Subtitles = new List<Subtitle>(); 
    } 
} 


public void CreateDB(object context) 
{ 
    Type type = context.GetType(); 
    FieldInfo[] fields = type.GetFields(BindingFlags.Instance 
     | BindingFlags.NonPublic); 

    foreach (FieldInfo field in fields) 
    { 
     Type genericType = this.GetGenericType(field); 

     MethodInfo method = this.GetType().GetMethod("CreateTable"); 
     MethodInfo generic = method.MakeGenericMethod(genericType); 
     generic.Invoke(this, null); 
    } 

    foreach (FieldInfo field in fields) 
    { 
     Type genericType = this.GetGenericType(field); 

     MethodInfo method = this.GetType().GetMethod("AddKeys"); 
     MethodInfo generic = method.MakeGenericMethod(genericType); 
     generic.Invoke(this, null); 
    } 
} 

private Type GetGenericType(FieldInfo field) 
{ 
    Type fieldType = field.GetType(); 
    Type genericType = null; 
    // Where I believe is should be generic. 
    if (fieldType.IsGenericType && 
     fieldType.GetGenericTypeDefinition() == typeof(List<>)) 
    { 
     genericType = fieldType.GetGenericArguments()[0]; 
    } 
    else 
    { 
     throw new Exception("An array is needed"); 
    } 

    return genericType; 
} 

public void CreateTable<T>() 
{ 
    StringBuilder query = new StringBuilder(); 
    Type type = typeof(T); 

    query.Append(String.Format("CREATE TABLE {0} (", NamingGeneration.PlurializeName(type.Name))); 

    query.Append(this.AddFields(typeof(T).GetProperties())); 

    query.Append(")"); 

    SqlCommand command = new SqlCommand(); 

    command.CommandText = query.ToString(); 

    SqlExecuteRequest.Instance.ExecuteNonQuery(command); 
} 

private void AddKeys<T>() 
{ 
    Type type = typeof(T); 
    PropertyInfo[] properties = type.GetProperties(); 

    IEnumerable<PropertyInfo> keyedProperties = properties.Where(x => x.Name.Contains("Id")); 

    foreach (PropertyInfo property in keyedProperties) 
    { 
     if (property.Name == "Id") 
     { 
      this.AddPrimaryKey(type.Name, property.Name); 
     } 
     else if (property.Name.EndsWith("Id")) 
     { 
      this.AddForeignKey(type.Name, property.Name); 
     } 
    } 
} 
+0

Можете ли вы рассказать нам немного больше о реальной проблеме, которую вы пытаетесь решить? В большинстве случаев вам не понадобится эта информация, чтобы написать полезный общий код. –

+4

Вы не указали ни один из методов, на которые вы размышляете. – Servy

+0

Моя цель - использовать мой метод CreateTable () для каждого поля в моем контексте. Мой контекст должен иметь только поля списка . – Kadgiko

ответ

5

Чтобы исправить код, как вы есть, вместо того,

Type fieldType = field.GetType(); 

Вы хотите

Type fieldType = field.FieldType; 

И это будет работать. FieldInfo - это то, что вы проходите. Когда вы вызываете GetType(), тип, который вы получаете, является информацией типа FieldInfo. ПолеInfoInfo содержит информацию о поле, а информация типа хранится в поле FieldInfo.FieldType.

Если вы пройдете через этот код, вы увидите это поведение. Отладка полезна.

Смежные вопросы