.Net动态创建类型传入泛型方法报错,求可行实现方案
问题:通过动态类型调用泛型MongoDB查询方法报错
我正在开发一个可复用的小型控制台应用程序,用于从MongoDB中获取信息。我编写了一个查询数据库的方法,返回类型为IMongoQueryable<T>。由于是控制台应用,我希望通过参数传入要使用的类/类型。但在以下代码中,调用GetDetails<typeArgument>(connectionString, db, collection)时出现错误:
CS0118 'typeArgument' 是变量,但被当作类型使用
代码如下:
void Main() { var connectionString = "connectionString"; var db = "dbName"; var collection = "CollectionName"; var activityId = 992018; string typeName = "Simon.AgentActivityDetails"; Type typeArgument = Type.GetType(typeName); var result = GetDetails<typeArgument>(connectionString, db, collection); //<-- 错误位置 } public IMongoQueryable<T> GetDetails<T>(string connectionString, string db, string collection) { var dbClient = new MongoClient(connectionString); IMongoDatabase _mongoDb = dbClient.GetDatabase(db); IMongoQueryable<T> result = _mongoDb.GetCollection<T>(collection).AsQueryable(); return result; }
请问我想要实现的功能是否可行?如果可行,该如何实现?
解决方法
功能完全可行,问题出在你试图用变量作为泛型参数——泛型参数需要编译期确定的类型,或者通过反射实现动态调用。以下是两种可行方案:
方案一:通过反射调用泛型方法
因为你是通过字符串动态获取Type对象,只能用反射来调用泛型方法:
void Main() { var connectionString = "connectionString"; var db = "dbName"; var collection = "CollectionName"; string typeName = "Simon.AgentActivityDetails"; Type typeArgument = Type.GetType(typeName); // 获取泛型方法定义并生成特定类型的方法实例 var method = typeof(YourClassName).GetMethod("GetDetails").MakeGenericMethod(typeArgument); // 调用方法:静态方法第一个参数传null,实例方法传当前类实例 var result = method.Invoke(this, new object[] { connectionString, db, collection }); } public IMongoQueryable<T> GetDetails<T>(string connectionString, string db, string collection) { var dbClient = new MongoClient(connectionString); IMongoDatabase _mongoDb = dbClient.GetDatabase(db); return _mongoDb.GetCollection<T>(collection).AsQueryable(); }
注意:YourClassName需要替换为包含GetDetails方法的类名。调用后result类型为object,若需后续操作可转换为非泛型的IQueryable接口。
方案二:已知类型分支处理(无反射)
如果控制台应用的目标类型是已知的,可通过分支直接指定泛型参数,避免反射开销:
void Main(string[] args) { var connectionString = "connectionString"; var db = "dbName"; var collection = "CollectionName"; string typeName = args[0]; // 假设从命令行参数获取类型名 switch(typeName) { case "Simon.AgentActivityDetails": var result = GetDetails<Simon.AgentActivityDetails>(connectionString, db, collection); // 处理当前类型的查询结果 break; case "Another.BusinessType": var anotherResult = GetDetails<Another.BusinessType>(connectionString, db, collection); break; // 扩展其他已知类型分支 } } public IMongoQueryable<T> GetDetails<T>(string connectionString, string db, string collection) { var dbClient = new MongoClient(connectionString); IMongoDatabase _mongoDb = dbClient.GetDatabase(db); return _mongoDb.GetCollection<T>(collection).AsQueryable(); }
这种方式类型安全、性能更好,适合类型数量有限且可提前枚举的场景。
补充说明
泛型是编译期生成特定类型代码的机制,无法直接用运行期变量作为泛型参数。当类型只能在运行期确定时,反射是唯一选择,但需注意其带来的性能开销和类型安全风险。
内容的提问来源于stack exchange,提问作者Simon Price
相关产品推荐
相关产品推荐

