简体   繁体   中英

C# generics - possible to create a method with n Generic types..?

I don't think this is possible but here goes...

I want to add method that can handle n numer of generics. for example :

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

will work for one type

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

will work for two types

Is there a way to work with n types - eg

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

the reason I want to do this is to implement a static nhibernate helper method which can load from multiple assemblies - right now it works great for one assembly. My current method is as shown below:

        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];
    }

Where the line: m.FluentMappings.AddFromAssemblyOf(), I would like to add multiple types eg

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

}

Obviously this couldn't work I'm not completely dumb but I am not so hot on generics - can someone confirm that this isn't possible :-) ..? What would be the most elegant way of achieving this effect in your opinion..?

No - the arity of generic types and methods is fixed on a per-type/method basis.

That's why there are all the different Action<...> , Func<...> and Tuple<...> types in the framework.

Occasionally that's a shame, but it gets in the way relatively rarely, and I suspect all kinds of things would be a lot more complicated with variable arity.

Actually I just noticed this link - I have to go home now but I might try something like this later if it works:

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

I think if I passed in an array of types and looped through the types with reflection this would work.

As others have specified you cannot do:

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

but you CAN do:

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

For instance:

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# Interactive Window Output:

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

So, you could take in your types that you want (that conform to the generic) and loop through them and call your code like you specified. You could also NOT use generics and just take in params object[] somethings; but I'd recommend strongly typing it if you can.

If anyone sees this please let me know if I'm way off base or misunderstood the question... Thanks!

you seem to repeat the same mistake that newton once did perhaps. He has two cats one was bigger and the other was smaller. He made two holes in door, bigger hole for the bigger one and smaller one for smaller cat. Where as actually he needed one big hole to assist both the cat.

Why don't you create one single method that can deal with as many as types you want..

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM