我可以从字符串开始并实例化该字符串的对象吗?

时间:2009-01-11 12:30:43

标签: c# .net asp.net linq-to-sql

我目前正在使用LINQ和C#。

我在LINQ to SQL模型中有一个表的DropDownList。

我希望用户能够从DropDown中选择LINQ表名。在代码中,我想创建一个LINQ类的实例,然后运行Select或它或我想要的任何其他东西。

如何根据用户选择的字符串中的对象名称完成对象的创建?我从一开始就想错了吗?

5 个答案:

答案 0 :(得分:6)

您需要Type.GetType(string)Activator.CreateInstance(Type)

请注意,Type.GetType(string)只会查找当前正在执行的程序集和mscorlib,除非您指定包括程序集的完整类型名称。在任何一种情况下,您都需要指定包含名称空间的类型名称。

另一种方法是在调用Activator.CreateInstance之前使用Assembly.GetType(string)直接从字符串中获取类型。

(这里实际上有很多的替代品。如果这些都没有帮助你,请发布更多信息,我相信我们可以找到方法。)

答案 1 :(得分:3)

由于您使用ASP.NET标记了帖子,我假设列表位于客户端。如果是这种情况,您应该非常小心地信任该数据,我不建议直接从用户输入创建类型。您可以将数据用作工厂的输入,然后可以返回正确的实例(并根据需要处理任何非法输入)。

答案 2 :(得分:1)

使用LINQ-to-SQL,有一些特定的方法可以从数据上下文中执行此操作;基本上,db.GetTable。这会返回ITable,但使用无类型的ITable会有点棘手。你可以枚举它,至少......

要获得ITable,您通常需要Type,您可以使用Assembly.GetType using (var ctx = new MyDataContext()) { string name = "Customer"; // type name Type ctxType = ctx.GetType(); Type type = ctxType.Assembly.GetType( ctxType.Namespace + "." + name); ITable table = ctx.GetTable(type); foreach(var row in table) { Console.WriteLine(row); // works best if ToString overridden... } }

Type

当然,一旦拥有Activator,就可以使用 object newObj = Activator.CreateInstance(type); // TODO: set properties (with reflection?) table.InsertOnSubmit(newObj); 来创建新的实体实例:

    using (var ctx = new MyDataContext()) {
        string name = "Customers"; // property name
        ITable table = (ITable) ctx.GetType()
            .GetProperty(name).GetValue(ctx, null);
        foreach (var row in table) {
            Console.WriteLine(row); // works best if ToString overridden...
        }
    }

但是如果你想使用属性名称,那也可以使用:

Where

使用无类型数据运行过滤器(Expression)等非常棘手,因为构建{{1}}会很曲折。我可能会在那时开始切换到打字模型......

答案 3 :(得分:1)

阐述Brian Rasmussen的警告:类型应该受到限制,需要有意识的设计。优选地,“用户可实例化”类型应标记为可以使用反射验证的特定自定义属性。

答案 4 :(得分:0)

关注Marc Gravell的回答。

按照他的建议,我注意到Cast<TResult>扩展方法(在System.Linq中定义)。

很遗憾,您似乎无法使用type实例进行投射:

Type dcType = dc.GetType();
Type type = dcType.Assembly.GetType(String.Format("{0}.{1}", dcType.Namespace, name));
var row = dc.GetTable(type).Cast<type>().SingleOrDefault(i => i.ID == 123);