【问题标题】:c# pass class as a parameterc#将类作为参数传递
【发布时间】:2015-04-12 00:57:49
【问题描述】:

我想传递一个类作为参数。

所以我想做的是传递一个类,例如:“客户”给一个方法。 我想这样做是因为我也可以将例如:“合同”作为类传递给同一方法。这样我就不需要为每个类都创建一个方法了。

附加信息:我正在使用 EntityFramework 6、MVC 5、Nest 1.0 和 ElasticSearch 1.4

这个概念是我们将东西放在 ElasticSearch 中,然后我们可以进行搜索。 搜索查询是:

SearchElasticClient.Search<Customer>(body => body
                              .AllIndices()
                              .Size(500)
                              .Query(query => query
                                  .Bool(@bool => @bool
                                      .Must(must => must
                                          .QueryString(qs => qs
                                              .Query("XXXX"))))));

对于合同:

SearchElasticClient.Search<Contract>(body => body
                              .AllIndices()
                              .Size(500)
                              .Query(query => query
                                  .Bool(@bool => @bool
                                      .Must(must => must
                                          .QueryString(qs => qs
                                              .Query("XXXX"))))));

如您所见,如果我想搜索我们拥有的每种类型,那么我需要复制粘贴此查询至少 20 次。

我不喜欢复制粘贴,因为代码不正确,当我需要更改它时,工作量很大。

所以我想创建一个方法,将我的类作为参数或类似的东西,这样我就可以创建一个通用方法来重用这段代码。

所以对于我们的例子:

我的(实体框架)类:

public class Customer{
    public int CustomerID {get;set;}
    public String CustomerName {get;set;}
}

public class Contract{
    public int ContractID {get;set;}
    public String ContractName {get;set;}
}

类之间的关系对我来说无关紧要,所以我将它们排除在外。

然后在我的 HomeController 中我想要类似的东西

public class HomeController : Controller
{
  ...

     public ActionResult Search(String textToSearch)
    {
        //So here you see that I want to use the same method for both classes.
        Customer customer = Helpers.SearchHelper.Search(textToSearch);
        Contract contract = Helpers.SearchHelper.Search(textToSearch);
    }
}

那么我的 SearchHelper 会是这样的:

public static class SearchHelper
{
     public static ElasticClient SearchElasticClient
        {
            get
            {
                Uri uri = new Uri("http://localhost:9200");
                var setting = new ConnectionSettings(uri, "default_INDEX");
                return new ElasticClient(setting);
            }
        }

        public static void SearchTest(String textToSearch, MyClass)
        {
            var test = SearchElasticClient
                            .Search<Customer>(body => body
                              .AllIndices()
                              .Size(500)
                              .Query(query => query
                                  .Bool(@bool => @bool
                                      .Must(must => must
                                          .QueryString(qs => qs
                                              .Query("XXXX"))))));

        }
}

如您所见,现在我将我的类“客户”设置为固定在我的代码中。 我想用变量或其他东西替换它。

现在我已经尝试过

    public static void SearchTest<T>(String textToSearch)
    {
        var test = SearchElasticClient
                        .Search<T>(body => body
                          .AllIndices()
                          .Size(500)
                          .Query(query => query
                              .Bool(@bool => @bool
                                  .Must(must => must
                                      .QueryString(qs => qs
                                          .Query("XXXX"))))));

    }

这里出现编译错误:“无法将 lambda 表达式转换为类型 'Nest.ISearchRequest',因为它不是委托类型。”

我不熟悉委托及其工作原理以及我是否可以使用它,所以如果我需要委托,请提供足够的详细信息。

我也试过了:

    public static void SearchTest(String textToSearch, Type myClass)
    {
        var test = SearchElasticClient
                        .Search<myClass>(body => body
                          .AllIndices()
                          .Size(500)
                          .Query(query => query
                              .Bool(@bool => @bool
                                  .Must(must => must
                                      .QueryString(qs => qs
                                          .Query("XXXX"))))));

    }

然后它给了我编译错误:“找不到类型或命名空间'myClass'。”我明白为什么会出现这个错误,所以我知道它更像是 public static void Search(..){..} 但我不知道如何实现它。

我希望这是对我的问题的更好解释。

所以这是“Nest”搜索的实现,我想避免复制粘贴搜索查询。

提前致谢

【问题讨论】:

  • 你需要传递类的实例而不是类本身。
  • @WindRaven 但他不想发送类的实例;他只想为方法提供类型,而不是实例。
  • @Servy 现在代码更有意义了。泛型将是要走的路,但对于 lamda,它不会很好地工作。有关确切用例的更多信息将在此处有所帮助,您要搜索什么以及是否可以使用反射。
  • 我现在不在办公室,但我知道我的问题不清楚。 ik willen 创建/更新问题,提供更多细节和更好的示例。感谢大家的 cmets 并对错误的描述表示抱歉

标签: c# lambda elasticsearch asp.net-mvc-5 nest


【解决方案1】:

我相信你想要做的是使Search 通用

public static classToPass Search<classToPass>()

那就这样用吧

Test x = Helper.Search<Test>(); //Test = class as definied above
TestTwo y = Helper.Search<TestTwo>();

【讨论】:

  • 我试过了,但由于 lambda 无法编译:s
  • @Boeykes 你应该创建一个关于如何让你的方法中的代码工作的新问题。
【解决方案2】:

使Search 方法通用。泛型参数或多或少是一个类型的参数,而不是一个对象。

【讨论】:

    【解决方案3】:
    public static class Helper
    {
        public static object Search<T>(T classToPass)
        {
            SearchElasticClient
                                  .Search<T>(body => body
                                    .AllIndices()
                                    .Size(500)
                                    .Query(query => query
                                        .Bool(@bool => @bool
                                            .Must(must => must
                                                .QueryString(qs => qs
                                                    .Query("XXX"))))));
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-30
      • 2021-09-07
      • 2016-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多