【问题标题】:C# generics - possible to create a method with n Generic types..?C# 泛型 - 可以创建具有 n 泛型类型的方法..?
【发布时间】:2010-09-15 11:14:18
【问题描述】:

我不认为这是可能的,但这里是......

我想添加可以处理 n 个泛型的方法。例如:

bool<T> MyMethod() where T: Isomething
{
}

适用于一种类型

bool<T,K> MyMethod() where T: Isomething
{
}

适用于两种类型

有没有办法使用 n 类型 - 例如

bool<T[]> MyMethod() where T: Isomething
{
}

我想这样做的原因是实现一个静态的 nhibernate 辅助方法,它可以从多个程序集加载 - 现在它适用于一个程序集。我目前的方法如下图:

        public static ISessionFactory GetMySqlSessionFactory<T>(string connectionString, bool BuildSchema)
    {
        //configuring is meant to be costly so just do it once for each db and store statically
        if (!AllFactories.ContainsKey(connectionString))
        {
            var configuration =
            Fluently.Configure()
            .Database(MySQLConfiguration.Standard
                      .ConnectionString(connectionString)
                      .ShowSql() //for development/debug only..
                      .UseOuterJoin()
                      .QuerySubstitutions("true 1, false 0, yes 'Y', no 'N'"))
            .Mappings(m =>
                      {
                          m.FluentMappings.AddFromAssemblyOf<T>();
                          m.AutoMappings.Add(AutoMap.AssemblyOf<T>().Conventions.Add<CascadeAll>);
                      })
            .ExposeConfiguration(cfg =>
                                 {
                                     new SchemaExport(cfg)
                                     .Create(BuildSchema, BuildSchema);
                                 });
            AllFactories[connectionString] = configuration.BuildSessionFactory();
        }

        return AllFactories[connectionString];
    }

所在行:m.FluentMappings.AddFromAssemblyOf(),我想添加多种类型例如

foreach(T in T[]){
   m.FluentMappings.AddFromAssemblyOf<T>()

}

显然这行不通我并不完全愚蠢,但我对泛型并不那么热 - 有人可以确认这是不可能的:-) ..?在您看来,实现这种效果的最优雅的方式是什么..?

【问题讨论】:

  • 正如 Jon 所指出的,这不是 C# 或 CLR 类型系统的特性。如果您对这种类型系统感兴趣,请考虑阅读 Haskell 中更高级别的类型。
  • @Eric - 谢谢 - 我刚开始研究 Haskell,看起来是一门非常有趣的语言。

标签: c# .net nhibernate generics


【解决方案1】:

否 - 泛型类型和方法的数量是固定在每个类型/方法的基础上的。

这就是为什么框架中有所有不同的Action&lt;...&gt;Func&lt;...&gt;Tuple&lt;...&gt; 类型。

有时这是一种耻辱,但它相对很少妨碍,而且我怀疑各种事情会因可变数量而变得更加复杂。

【讨论】:

  • 谢谢-这是一个答案-即这是不可能的,但是您对如何完成有任何建议-是否有任何反射等可用于循环遍历列表类型并基于它们创建泛型?例如将类型作为数组传递?我几乎想给你一个正确的分数来教我一个新单词。现在我将尝试将 arity 放入尽可能多的句子中。
  • @Mark:我怀疑你目前最好的选择就是重载方法。 (您可以通过 arity 重载。)或者,使该方法返回 bool 以外的其他内容,以便您可以以链式/流畅的方式多次调用它。
  • 谢谢 - 我什至没有想到将其设置为流利的 - 这正是我要做的!像 NHelper(ConnectionString).From().From().Build() 之类的东西 - 太棒了!
【解决方案2】:

实际上我刚刚注意到这个链接 - 我现在必须回家,但如果它有效,我可能会在以后尝试这样的事情:

http://geekswithblogs.net/marcel/archive/2007/03/24/109722.aspx

我想如果我传入一个类型数组并通过反射循环遍历这些类型,这将起作用。

【讨论】:

    【解决方案3】:

    正如其他人指定的那样,您不能这样做:

    bool MyMethod<T[]>() where T: ISomething
    

    但你可以做到:

    bool MyMethod<T>(params T[] somethings) where T : ISomething
    

    例如:

    public interface ISomething { string Name { get; set; } }
    
    public class SomethingA : ISomething { public string Name { get; set; } = nameof(SomethingA); }
    public class SomethingB : ISomething { public string Name { get; set; } = nameof(SomethingB); }
    
    void MyMethod<T>(params T[] somethings) where T : ISomething
    {
        foreach (var something in somethings)
        {
            if (something != null)
                Console.WriteLine(something);
        }
    }
    
    // Use it!
    ISomething a = new SomethingA();
    ISomething b = new SomethingB();
    
    // You don't need to specify the type in this call since it can determine it itself.
    MyMethod(a, b);
    
    // If calling it like this though you do:
    MyMethod<ISomething>(new SomethingA(), new SomethingB());
    

    C# 交互式窗口输出:

    > MyMethod(a, b);
    Submission#0+SomethingA
    Submission#0+SomethingB
    > 
    > MyMethod<ISomething>(new SomethingA(), new SomethingB());
    Submission#0+SomethingA
    Submission#0+SomethingB
    

    因此,您可以获取您想要的类型(符合泛型)并遍历它们并按照您指定的方式调用您的代码。你也可以不使用泛型,只接受 params object[] 的东西;但如果可以的话,我强烈建议您输入它。

    如果有人看到这个,请让我知道我是否离题或误解了这个问题...谢谢!

    【讨论】:

      【解决方案4】:

      你似乎在重复牛顿曾经做过的同样的错误。他有两只猫,一只较大,另一只较小。他在门上打了两个洞,大的洞给大的猫,小的洞给小猫。实际上他需要一个大洞来帮助两只猫。

      为什么不创建一个可以处理任意数量类型的单一方法..

      bool<T[]> MyMethod() where T: Isomething
      {
      }
      

      【讨论】:

      • 谢谢,但我不确定您是否正确阅读了这个问题。我并没有创造 3 种不同的方法——只是想说明一个观点。即第三个无效,但这是我需要做的事情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 2018-08-28
      相关资源
      最近更新 更多