-1

How can I pass the T by parameter but I need to do something like this:

Added: I need to create one thread for each SqlServerTable object, and it is a Datatable, but into my method CheckChanges my datatable is converted to my objects inherited from IHasId

>     class Account: IHasId<int>
>     class Requisition: IHasId<int>
>     class EtcEtc: IHasId<int>

I need to pass those classes type by parameter such as: tableItem.TableType

and below I pass the T from that, I can't pass the T when I call the method because It comes from a object parameter dinamically

public static void Start()
{
    SqlServerTables.ForEach(tableItem =>
    {
        T t = (T)tableItem.TableType; // <- THIS IS WHAT I NEED WORKING.. :(
        var destinationTable = SqlServerDb.LoadDestination(tableItem.Table.TableName, tableItem.Table.PrimaryKey[0].ColumnName, false);
        // HOW CAN I GET THE <T> below?
        var thread = new Thread(() => SincronizeTable<T>(destinationTable)) { Name = tableItem.Table.TableName };
        thread.Start();
    });
}

private static void SincronizeTable<T>(DataTable sqlServerTable)
{
    var tableName = sqlServerTable.TableName;
    var primaryKey = sqlServerTable.PrimaryKey[0].ColumnName;

    while (_isAlive)
    {
        var sourceTable = TaskDb.LoadDataFromTask(tableName, primaryKey, true, false);
        var destinationTable = SqlServerDb.LoadDestination(tableName, primaryKey, false);

        var differences = Migration.CheckChanges<T>(sourceTable, destinationTable, false, primaryKey);

        // Save changes
        var success = Migration.SaveChanges(differences, tableName, primaryKey, Program.ArgumentParams.BatchUpdateQuantity);

        Thread.Sleep(1000);
    }
}
}
Roger Oliveira
  • 1,589
  • 1
  • 27
  • 55
  • 1
    `Type t = typeof(T)`? Your question is not clear at all. – Erik Philips May 05 '15 at 01:57
  • sorry I will make it better now.. – Roger Oliveira May 05 '15 at 01:58
  • 1
    You don't mean `T t = (T)myObject;`? – Enigmativity May 05 '15 at 01:58
  • 2
    Generics are a compile-time feature. You can't do this dynamically. – Blorgbeard May 05 '15 at 02:00
  • I added my codes, could you have a look, I have a thread, and I need to pass by parameter dynamically the object that I have for using in the method: CheckChanges @Enigmativity – Roger Oliveira May 05 '15 at 02:01
  • 1
    I don't see what assigning the variable `t` will do, you aren't using it.. – Erik Philips May 05 '15 at 02:03
  • 1
    @RogerOliveira - Can you please use the "@" messaging notation to make it clear who you are replying to and to raise notifications? – Enigmativity May 05 '15 at 02:03
  • 1
    You seem to be confused about how generics work. I suggest you try a much simpler example. – John Saunders May 05 '15 at 02:05
  • 1
    @Blorgbeard that's not exactly true, generics are handled at runtime https://msdn.microsoft.com/en-us/library/f4a6ta2h.aspx – Keith Nicholas May 05 '15 at 02:05
  • 1
    It seems like you are trying to dynamically invoke a generic method given that you have a reference to the `Type` of the generic parameter. – Enigmativity May 05 '15 at 02:06
  • Yes t is not in use, it was a misunderstanding, but I do need to use CheckChanges how can I get this in that scenario? @ErikPhilips – Roger Oliveira May 05 '15 at 02:06
  • 1
    @KeithNicholas yeah, I know, but I didn't want to get into `MakeGenericMethod` etc, because this question didn't seem like a good candidate for reflection. – Blorgbeard May 05 '15 at 02:09
  • @KeithNicholas I do know that I might have done this method wrong, however, looking at my needs, which is using the method CheckChanges do you see any solutions even though changing my structure? – Roger Oliveira May 05 '15 at 02:10
  • 1
    You need to explain why you need something and **exactly** what you need. Your question and code are still confusing. `` is a generic type definition, saying you need `` doesn't make sense. – Erik Philips May 05 '15 at 02:11
  • Duplicate of http://stackoverflow.com/questions/325156/calling-generic-method-with-a-type-argument-known-only-at-execution-time – Erik Philips May 05 '15 at 02:15
  • In your call to `CheckChanges`, what is `T` the type of? – John Saunders May 05 '15 at 02:15
  • 1
    How many tables do you have? – John Saunders May 05 '15 at 02:17
  • @JohnSaunders they are many classes which represent my Entities such as: Account: IHasId, Requisition:IHasId – Roger Oliveira May 05 '15 at 02:19
  • @JohnSaunders I have around 10 tables – Roger Oliveira May 05 '15 at 02:19
  • 1
    Are you certain that it's even _necessary_ to do this in parallel? And, if you only have 10 tables, and if the set of tables doesn't change frequently, then I would just do it inline. Just repeat the task start code 10 times. That's not a tragedy. – John Saunders May 05 '15 at 02:23
  • @JohnSaunders, yeah I think you are right, I just wanted to do it very dynamically, I have fixed number of tables, as this is a Console Application in order to replicate data from several tables in MSAccess to SqlServer.... – Roger Oliveira May 05 '15 at 02:26
  • 1
    Were you aware you can do this in SQL Server Management Studio (SSMS). It will even create an SSIS (SQL Server Integration Services) package which you can use to perform the operation whenever you want. And, BTW, though it is not dynamic, it _does_ perform the operations in parallel. – John Saunders May 05 '15 at 02:27
  • @JohnSaunders I have spent days and days trying to use SSIS, the slowly change dimension couldn't deal with large amounts of data... this was the only solution I could use, anyways, I didn't try the Linked Server, in which I didn't try to understand it, And my Sql Server is Express... doesn't have SSIS – Roger Oliveira May 05 '15 at 02:38

2 Answers2

2

It sounds like you want to dynamically call a generic method.

Here's how:

Starting with a simple type:

public class Foo
{
}

And a simple method in a class:

public class Bar
{
    public void DoSomething<T>()
    {
        Console.WriteLine(typeof(T).FullName);
    }
}

Then you can call it this way:

Foo foo = new Foo();

Type type = foo.GetType();

Bar bar = new Bar();

bar
    .GetType()
    .GetMethod("DoSomething")
    .MakeGenericMethod(type)
    .Invoke(bar, null);
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • Here is a version of the invoke line that avoids the magic string `((Action)bar.DoSomething).Method.GetGenericMethodDefinition().MakeGenericMethod(type).Invoke(bar, null);` Replace `(Action)` with whatever `Action`, `Action`, `Func`, etc you need to specify the correct method overload. Also note that the type specified `` is discarded and only needs to match the method constraints. – Grax32 May 05 '15 at 17:20
1

It seems that you want to supply T to a generic method.

public void MyMethod<T>(Class1 myClass)
{
}

Instead of requiring the type declaration, you can derive it by passing the type.

public void MyMethod<T>(Class1 myClass, T someClass)
{
}

If you only have the type and not an instance of the type, then this is a duplicate of Calling generic method with a type argument known only at execution time.

Community
  • 1
  • 1
Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • I don't think he has `T` at run-time. He just has `tableItem.TableType` - which I assume is of `System.Type`. – Enigmativity May 05 '15 at 02:17
  • Yeah I'm not sure, I don't know what `tableItem.Table` is. Seems like it's an instance of `tableItem.TableType` but I don't know. – Erik Philips May 05 '15 at 02:18
  • @ErikPhilips Actually that code is not finished, I might have done it wrong, Basically I need to send the class type to my method CheckChanges, and the tricky is where can I store this class type? I can create a property in SqlServerTable object to have the class type.. That's my idea. what do you think? – Roger Oliveira May 05 '15 at 02:23
  • Why do you need to pass the type? Why can't you pass the instance? – Erik Philips May 05 '15 at 03:09