Create a generic method in C #

I have the following structure:

public enum MyTypes { Type1 = 1, Type2 = 2, Type3 = 3 } public abstract class class1 { int id; string name; MyType type; } public class class2 : class1 { } public class class3 : class1 { } public class class4 : class1 { } 

now what i want to do is make a generic method, i want to give it an object type say class 3 and it will create an object from class 3 and define its variables and return it to add it to class1 list

like

 private class1 myFunction (MyType t , int id , string name) { T obj = new T(); obj.type = t ; obj.id = id ; obj.name = name; return obj; } 

How to create this general method?

Please help me as soon as you can

Thanks at Advance

+4
source share
5 answers

As Danny Chen says in his answer, you have to change the definitions of your class a bit to make it work, then you can do something like the following:

 public T myFunction<T>(int id, string name) where T : class1, new() { T obj = new T(); obj.id = id; obj.name = name; return obj; } 

This general method requires that a parameter of type T be obtained from class1 , and also have a constructor without parameters - which means where T : class1, new() .

Since the id and name properties are defined through the base class class1 , you can set them to everything that was passed to myFunction through its parameters.


A few more notes about class1 :

  • Consider creating a class1 interface instead of an abstract class, as it does not contain any functionality.
  • id , name , type must be public if you really want to have access to them.
  • Usually fields are not actually displayed as public . Instead, consider using properties.
+13
source

No, this is not possible because all these classes are abstract (cannot be created). We cannot create an instance of an abstract class.

+2
source

If I understand correctly, you are asking how to create a Factory template. This is exactly what this template is for: specify the type of object you want and it will return it to you.

Alternatively, you can use the type switch in your function.

 private class1 myFunction (MyType t , int id , string name) { class1 obj; switch(t) { case MyTypes.Type1: obj = new Class1(); ... } obj.type = t ; obj.id = id ; obj.name = name; return obj; } 

The third approach is to use generics.

 private T myFunction<T>(MyType t , int id , string name) where T : class1, new() { T obj = new T(); obj.type = t ; obj.id = id ; obj.name = name; return obj; } 

You would call it that:

 var obj = myFunction<Class3>(MyTypes.Type3, 5, "some name"); 
0
source

What you are looking for is basically an abstract factory design template. http://en.wikipedia.org/wiki/Abstract_factory_pattern

do something like the following

 private class1 createSpecializedType<T>(MyType t, int id, string name) where T: class1, new() { T obj = new T(); obj.type = t ; obj.id = id ; obj.name = name; return obj; } public class1 createMyType(MyType t, int id, string name) { switch(t) { case Type1: return this.createSpecializedType<class2>(t, id, name); case Type2: return this.createSpecializedType<class3>(t, id, name); case Type3: return this.createSpecializedType<class4>(t, id, name); } } 

The code is not verified and should be considered as pseudo-code.

This will allow you to call createMyType, and it will find out which class you need in the parameters and return the correct object to you.

PS: Of course, classes are abstract and cannot be used. But I suspect that it was an error that occurred when copying / rewriting code.

0
source

If I understand you correctly, MyTypes , and the actual type of the class expresses the same thing. In this case, you need to have some kind of mapping from your MyTypes to the actual classes, for example:

 static Dictionary<MyTypes, Type> typeMapping = new Dictionary<MyTypes, Type> { { MyTypes.Type1, typeof(class2) }, { MyTypes.Type2, typeof(class3) }, { MyTypes.Type2, typeof(class4) }, }; 

Then you can use reflection to create an instance of the specified type:

 private class1 myFunction(MyType t, int id, string name) { class1 obj = (class1)typeMapping[t].GetConstructor(Type.EmptyTypes).Invoke(null); obj.type = t ; obj.id = id ; obj.name = name; return obj; } 
0
source

All Articles