如何在 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。