c# - 来自字符串类型名称的强类型对象 (C#)

标签 c# reflection

如果您查看以下代码,您将(希望)看到我正在尝试实现的目标。这段代码基本上是:

  • 查询通用存储项(它们将其类型存储为字符串)
  • 如果该项是 SearchCriteria 的子类,则创建正确的实例
  • 将实例添加到列表中(SearchCriteria 是父类(super class))

当然,伪开关案例不是很优雅,我必须根据我创建的所有不同标准对其进行更新。

那么,我的问题是,是否有一种“通用”方法来创建一个强类型实例,该实例使用字符串作为该类型的“源”。

我知道我可以使用反射创建一个实例,但这是对象类型,所以我无法将它添加到列表中。哦,刚刚有了一个想法......使用反射创建对象,将其转换为父类(super class)型(SearchCrit),添加到列表中。我希望真正的类型仍然是“正确的子类型”......

将尝试一下,并用结果更新这篇文章。有更好的想法吗?

克里斯

   private IList<SearchCriteria> _searchCriteriaAll;
    public IList<SearchCriteria> SearchCriteriaAll
    {
        get
        {
            if (_searchCriteriaAll == null)
            {
                _searchCriteriaAll = new List<SearchCriteria>();
                var tN = typeof (SearchCriteria).ToString();
                foreach (var o in DataStorage.LinkedObjects)
                {
                    if (tN.StartsWith(o.TypeName))
                    {
                        if (o.TypeName == typeof(StringSearchCriteria).ToString())
                            _searchCriteriaAll.Add(new StringSearchCriteria(o));
                    }
                }
            }
            return _searchCriteriaAll;
        }
    }

编辑:

感谢您的提示,“正确”的方式肯定是工厂模式。我会调查的。现在,我使用这个 hack,因为子类太小了,我不想为每个子类都有一个工厂..(这个地方目前是唯一一个具有这种“奇特”功能的地方)

   private IList<SearchCriteria> _searchCriteriaAll;
    public IList<SearchCriteria> SearchCriteriaAll
    {
        get
        {
            if (_searchCriteriaAll == null)
            {
                _searchCriteriaAll = new List<SearchCriteria>();
                var tN = typeof (SearchCriteria).ToString();
                foreach (var o in DataStorage.LinkedObjects)
                {
                    if (tN.StartsWith(o.TypeName))
                    {
                        var newO = Activator.CreateInstance(typeof(SearchCriteria).Assembly.FullName, o.TypeName);
                        var newCrit = newO.Unwrap() as SearchCriteria;
                        newCrit.DataStorage = o;
                        _searchCriteriaAll.Add(newCrit);
                    }
                }
            }
            return _searchCriteriaAll;
        }
    }

最佳答案

泛型和反射不是好 friend 。这里一个更简单的方法是使用非通用列表接口(interface):

_searchCriteriaAll = new List<SearchCriteria>();
IList list = (IList) _searchCriteriaAll;
...
Type type = typeof(SearchCriteria).Assembly.GetType(o.TypeName);
list.Add(Activator.CreateInstance(type));

(其中 o.TypeName 包括命名空间信息,但不必是程序集限定的)

这仍然是运行时类型安全的(如果错误会在运行时抛出),并且仍然调整相同的列表。

另请注意,我们仅通过 Assembly.GetType() 直接查看 Assembly 内部。

关于c# - 来自字符串类型名称的强类型对象 (C#),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2168565/

相关文章:

c# - 在执行期间创建 Windows 窗体控件

c# - 将下拉列表中的时间值添加到 DatePicker 值

c# - 快速启动简单的 C# FileSystemWatcher Windows 服务

c# - 使用反射从复杂类中获取值

c# - 如何与字符串数组和字符串进行比较

c# 解析 UTC 日期时间

java - 我怎样才能得到一个类对象形式的原语?

java - 我可以使用反射发现 Java 类的声明内部类吗?

java - 在java中使用反射查找复合类的所有属性

Swift 镜像反射不返回 UIVIew 上的属性