如何在 C# 中使用 class 名称作为方法中的参数?
How do I use class names as parameters in methods in C#?
作为面向对象编程语言的初级程序员,我最近开始学习 C#。我目前正在制作一个网络应用程序,如下所示:
该网页由几个下拉菜单组成,这些菜单应该填充来自 MongoDB 数据库的结果。在这个数据库中,我有 8 个集合,每个集合都有未知数量的对象,每个集合有 7 个属性(和一个集合名称)。我已经为集合之间的所有相似之处使用了一个界面,如下所示:
namespace TestMVC.Models
{
public interface Product
{
string collectionName;
ObjectId Id { get; set; }
double Prijs { get; set; }
string Productlink { get; set; }
string Productnaam { get; set; }
}
}
然后我想执行一个 select 查询以使用下面显示的代码显示特定集合的每条记录:
var collection = DatabaseConnect().GetCollection<Product>(collectionName);
var query =
from Product in collection.AsQueryable<Product>()
orderby Product.Prijs
select Product;
foreach (Product prd in query){
//... Do something
}
这是我的问题开始的地方。我事先不知道在运行时检索到什么集合,所以我试图创建一个具有 2 个参数的通用函数来处理数据库中的所有 8 种类型的集合。
public string databaseResult(string collectionName, Type className)
我使用以下方式称呼它:
databaseResult('motherboards', typeof(Motherboards));
因此,当我将所有这些注入到上述代码中时,我在以下行中收到错误
var collection = DatabaseConnect().GetCollection<className>(collectionName);
说:
"The type or namespace name "className" could not be found (are you missing a using directive or an assembly reference?)"
这显然意味着代码没有将 <> 符号之间的 "className" 视为参数中声明的 class 名称...所以这是我的问题。
我首先尝试在参数中使用 "class" 而不是 "Type",这显然不起作用,因为 "class" 不是类型(显然)。我在堆栈溢出上搜索了一下,并学会了使用 typeof 来 return class 名称...这仅在您需要实例化所述 class 的对象时才有用。不幸的是 MongoDB 不能与 classes 的实例一起正常工作:它需要与 classes 本身一起工作(据我所知)。
上面的段落只是为了告诉你我自己做了一些研究,但我对 msdn.com 上介绍的 C# 行话一头雾水。我正在寻找一个答案,它能让我明白要做什么才能使这段代码工作,为什么,以及对后者的解释(最好没有我之前提到的 msdn.com 行话)。
对于阅读时间过长,我深表歉意,但我仍然希望有人愿意提供帮助。非常感谢。
为此你必须使用 generics。
public string DatabaseResult<T>(string collectionName)
where T : IProduct
{
var collection = DatabaseConnect().GetCollection<T>(collectionName);
// ...
}
你这样称呼它:
DatabaseResult<Motherboard>("motherboards");
在此示例中,T
是一个类型的占位符。它被替换为 Motherboard
.
注意 where T : IProduct
子句。它在 T
上设置了一个约束,只允许 class 实现 IProduct
.
这是可行的,因为您可以在需要类型名称的地方使用 T
(例如 typeof(T)
)。另一方面,当您在代码中使用 Type className
参数时,className
就像任何其他变量一样只是一个变量。 Type
class 没有任何特殊之处,所以你不能写 typeof(className)
或 GetCollection<className>
例如,因为 类型名称 应该在那里,而不是持有对 Type
实例的引用的变量。
此外,作为C#中的约定,接口应以I
开头(即IProduct
),方法名称应为PascalCased。
作为面向对象编程语言的初级程序员,我最近开始学习 C#。我目前正在制作一个网络应用程序,如下所示:
该网页由几个下拉菜单组成,这些菜单应该填充来自 MongoDB 数据库的结果。在这个数据库中,我有 8 个集合,每个集合都有未知数量的对象,每个集合有 7 个属性(和一个集合名称)。我已经为集合之间的所有相似之处使用了一个界面,如下所示:
namespace TestMVC.Models
{
public interface Product
{
string collectionName;
ObjectId Id { get; set; }
double Prijs { get; set; }
string Productlink { get; set; }
string Productnaam { get; set; }
}
}
然后我想执行一个 select 查询以使用下面显示的代码显示特定集合的每条记录:
var collection = DatabaseConnect().GetCollection<Product>(collectionName);
var query =
from Product in collection.AsQueryable<Product>()
orderby Product.Prijs
select Product;
foreach (Product prd in query){
//... Do something
}
这是我的问题开始的地方。我事先不知道在运行时检索到什么集合,所以我试图创建一个具有 2 个参数的通用函数来处理数据库中的所有 8 种类型的集合。
public string databaseResult(string collectionName, Type className)
我使用以下方式称呼它:
databaseResult('motherboards', typeof(Motherboards));
因此,当我将所有这些注入到上述代码中时,我在以下行中收到错误
var collection = DatabaseConnect().GetCollection<className>(collectionName);
说:
"The type or namespace name "className" could not be found (are you missing a using directive or an assembly reference?)"
这显然意味着代码没有将 <> 符号之间的 "className" 视为参数中声明的 class 名称...所以这是我的问题。
我首先尝试在参数中使用 "class" 而不是 "Type",这显然不起作用,因为 "class" 不是类型(显然)。我在堆栈溢出上搜索了一下,并学会了使用 typeof 来 return class 名称...这仅在您需要实例化所述 class 的对象时才有用。不幸的是 MongoDB 不能与 classes 的实例一起正常工作:它需要与 classes 本身一起工作(据我所知)。
上面的段落只是为了告诉你我自己做了一些研究,但我对 msdn.com 上介绍的 C# 行话一头雾水。我正在寻找一个答案,它能让我明白要做什么才能使这段代码工作,为什么,以及对后者的解释(最好没有我之前提到的 msdn.com 行话)。
对于阅读时间过长,我深表歉意,但我仍然希望有人愿意提供帮助。非常感谢。
为此你必须使用 generics。
public string DatabaseResult<T>(string collectionName)
where T : IProduct
{
var collection = DatabaseConnect().GetCollection<T>(collectionName);
// ...
}
你这样称呼它:
DatabaseResult<Motherboard>("motherboards");
在此示例中,T
是一个类型的占位符。它被替换为 Motherboard
.
注意 where T : IProduct
子句。它在 T
上设置了一个约束,只允许 class 实现 IProduct
.
这是可行的,因为您可以在需要类型名称的地方使用 T
(例如 typeof(T)
)。另一方面,当您在代码中使用 Type className
参数时,className
就像任何其他变量一样只是一个变量。 Type
class 没有任何特殊之处,所以你不能写 typeof(className)
或 GetCollection<className>
例如,因为 类型名称 应该在那里,而不是持有对 Type
实例的引用的变量。
此外,作为C#中的约定,接口应以I
开头(即IProduct
),方法名称应为PascalCased。