2017-08-29 51 views
7

我有一个实体框架代码第一个模型,我为其制作了一个静态泛型类,该类有一个搜索方法,该方法在列表中的每个项目都被调用。我认为让这个类变为静态可以提高代码的清晰度,甚至可以提高性能,因为我们不需要在很多不同的地方创建实例。 所有这些的目标是自动化用户可以搜索,导出等的属性。是否每次都调用MakeGenericType(...)多次创建一个新类型?

主要问题是:如果为具有引用类型属性的每个项目(可能为1000s)调用MakeGenericType(...),则为该引用类型属性的一般类型生成一次并保存在某处或生成1000个次?

指出任何其他表现的罪行或代码的气味,赞赏。

public static class SearchUserVisibleProperties<T> 
{ 
    private static List<PropertyInfo> userVisibleProperties { get; set; } 

    static SearchUserVisibleProperties() 
    { 
     userVisibleProperties = typeof(T).GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(UserVisibleAttribute))).ToList(); 
    } 

    public static bool search(T item, string searchString) 
    { 
     foreach (PropertyInfo pInfo in userVisibleProperties) 
     { 
      object value = pInfo.GetValue(item); 
      if (value == null) 
      { 
       continue; 
      } 
      if (pInfo.PropertyType == typeof(string) || pInfo.PropertyType.IsValueType) 
      { 
       ...unrelevant string matching code... 
      } 
      else if ((bool)typeof(SearchUserVisibleProperties<>).MakeGenericType(new Type[] { value.GetType() }).InvokeMember(nameof(search), BindingFlags.InvokeMethod, null, null, new object[] { value, searchString })) 
      { 
       return true; 
      } 
     } 
     return false; 
    } 
} 
+0

感谢您的问题!我总是认为每次都会创建一个新类型,并添加自己的缓存层来防止这种情况发生。事实上,我正在编写答案的代码,期望看到“False”打印两次。事实证明,我现在可以安全地删除我的缓存层! – dasblinkenlight

+1

请注意,'new Type [] {value.GetType()}'不是必需的,因为'MakeGenericType'的参数'typeArguments'是用'params'关键字声明的。一个新的数组可以创建任何方式,但它不会混乱你的代码。 – dasblinkenlight

+0

如果我删除'new Type [] {value.GetType()}'''它会抛出一个'ArgumentException'作为'class SearchUserVisibleProperties '有一个通用参数需要提供,对不对?所以我的代码没有明显的性能/气味改进?在组装好几个小时后感觉一点自豪感:)。感谢你的回答! – Tom

回答

7

Documentation of MakeGenericType表明类型返回泛型类型定义和通用类型参数的相同组合将是相同的:

通过MakeGenericType返回的Type对象是与由所获得的Type调用结果构造类型的GetType方法或使用相同类型参数从相同泛型类型定义创建的任何构造类型的GetType方法。

这里是一个小实验,证明了上面的是正确的:

相关问题