3

In C# I have a method

public string GetString<T>() where T : class

In the calling function I have only the name of the class which I want to pass to GetString()<T>. E.g. "MyClass". How can I convert "MyClass" to class? I tried it using Types but I couldn't find a conversion.

EDIT: The real example is from a database access class. The client asks for information for a specific hardware component. This component is specified by a string. Based on this string I want to access a table with a known name pattern. Not hard coding table names allows us to add/remove tables from the database without the need to change the C# code.

The function which returns the needed information exists already and needs a class as generic type.

E.g.

string tblName = "HW_" + hwComponentFromClient;
string retValue = GetString<GetClassByString(tblName)>();

I need something like a method:

class GetClassByString(string);
telandor
  • 869
  • 9
  • 28
  • 2
    Why do you have a string of your class? That seems to be the real issue. Why is it impossible to know at compile-time which class you want to use? – Tim Schmelter Apr 15 '16 at 12:54
  • If you don't know the class at compile time you are going do have to resort to reflection or dynamic, neither of which are compile-time type safe. Is there not a base class or interface that you can cast to? – D Stanley Apr 15 '16 at 14:14

1 Answers1

3

You can get the classname but you need to get it from the right assembly and pass the full name of the class (assembly name + class name, in my case "TestAlexander.Test").

class Program
{
   static void Main(string[] args)
   {
     Type classType = Assembly.GetExecutingAssembly().GetType("TestAlexander.Test");
     Test test = new Test();
     typeof(Test).GetMethod("TestMethod").MakeGenericMethod(classType).Invoke(test, null);
     Console.Read();
   }
}
public class Test
{
    public void TestMethod<T>() where T: class
    {
        Console.WriteLine("Great success!");
    }
}
Alexander Derck
  • 13,818
  • 5
  • 54
  • 76
  • The `instance` is not necessarily related to `classType` like in your case. So it is likely that he has "instance" already (maybe it is `this`), and I do not think the asker will need `Activator.CreateInstance`. – Jeppe Stig Nielsen Apr 15 '16 at 13:13
  • Thank you for your answer. I don't need to invoke a method though. I need the generic type 'class' only from knowing the class name. See also my edit. – telandor Apr 15 '16 at 13:13
  • @telandor Then the first line should do it, that gets the class. Going to edit – Alexander Derck Apr 15 '16 at 13:13
  • The question asks about calling `public string GetString() where T : class` when the type `T` is only known as the type name. This answer is in the right ballpark, but doesn't specifically answer the question. – Enigmativity Apr 15 '16 at 13:14
  • @Enigmativity Edited it. – Alexander Derck Apr 15 '16 at 13:20
  • 1
    I'll look at it into detail next week. But first tests showed that it does what I was looking for. Thank you very much for your help! – telandor Apr 15 '16 at 13:40
  • I would prefer: `class Program { public void TestMethod() where T: class { Console.WriteLine("Great success!"); } static void Main() { Type classType = Assembly.GetExecutingAssembly().GetType("RandomTestShit.Test"); Program program = new Program(); typeof(Program).GetMethod("TestMethod").MakeGenericMethod(classType).Invoke(program, null); Console.Read(); } } public class Test { }` I.e. having the type whose string representation we have, not contain the generic method in question. – Jeppe Stig Nielsen Apr 15 '16 at 14:40
  • @JeppeStigNielsen Both are kind of the same in my opinion, OP might have an object from another class that contains the method. The important parts from the question stay the same. (So far trying to edit out my "randomshittest" assembly :-( ) – Alexander Derck Apr 15 '16 at 14:48