为什么反射列表<t>不通用?</t>

时间:2014-09-09 19:15:35

标签: c# list generics

我无法理解为什么我的fieldType没有资格作为通用列表。我尝试使用下面提出的解决方案来获取列表的泛型类型。但当我到达fieldType.IsGenericType == false时,我感到非常惊讶,我不明白发生了什么。

我的目标是能够在我的上下文中为每个字段使用我的方法CreateTable()。我的上下文应该只有List字段。

这是我在我的对象中找到的信息:

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);
        }
    }
}

1 个答案:

答案 0 :(得分:5)

要修复代码,而不是

   Type fieldType = field.GetType();

你想要

Type fieldType = field.FieldType;

它会起作用。 FieldInfo是你通过的。当您调用GetType()时,您获得的类型是FieldInfo类型信息。 FieldInfo包含有关Field的信息,Type信息保存在FieldInfo.FieldType中。

如果您单步执行此代码,您会看到此行为。调试很有用。