开发者

Create Generic Method in C#

开发者 https://www.devze.com 2023-01-20 23:28 出处:网络
I have the following structure: public enum MyTypes { Type1 = 1, Type2 = 2, Type3 = 3 } public abstract class class1

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 to make a generic method , I want to give it the type of object say c开发者_如何转开发lass 3 and it will create object from class 3 and define it's variables and return it to be able to add it to a list of class1

like that

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 generic method ?

please Help me as soon as you can

Thanks in Advance


As Danny Chen says in his answer, you will have to modify your class definitions a little for it to work, then you could 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 generic method requires type parameter T to be derived from class1 and also to have a parameter-less constructor -- that's what the where T : class1, new() means.

Since id and name properties are defined through the class1 base class, you can then set these to whatever was passed into myFunction via its parameters.


Some more things to note about class1:

  • Consider making class1 an interface instead of an abstract class, as it doesn't contain any functionality.
  • id, name, type need to be public if you actually want to be able to access them.
  • Usually, fields aren't actually exposed as public. Consider using properties instead for that purpose.


No, it's impossible, because all these classes are abstract (can't be instantiated). We can't create an instance of an abstract class.


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

Alternatively, you could use a switch on the types 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;
}

A 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'd call it like:

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


If I understand you correctly, MyTypes and the actual type of the class expres the same thing. In that 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;
}


What you are looking for is basicly the abstract factory design pattern. 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);
    }
}

Code is not tested and should be considered pseudo code.

This will allow you to call createMyType and it will figure out which class you want by the parameters and return you the correct object.

PS: Of course the classes are abstract and cannot be instanciated. But I suspect this was an error introduced when copying/rewriting the code.

0

精彩评论

暂无评论...
验证码 换一张
取 消