-1

I am new to C# generics. I have several classes with identical methods. I want to create a generic class which will be of type belonging to any of those classes and invoke the methods from them. I am not sure whether this is possible, or there is a different way of doing it. I have given my code sample below. I have included two representative classes named, EastCoastStores and WestCoastStores. When I try to invoke the method using reflection, I am getting null reference exception for GetMethod("GetZipCode") in the GetZipCode() method of the MyGenerics class. I have searched the internet, but could not an appropriate solution.

//Two classes with identical methods
public class EastCoastStores
{
    private string zip;

    public void SetZipCode(string zip)
    { this.zip = zip; }

    public string GetZipCode()
    { return zip; }
 }

public class WestCoastStores
{
    private string zip;

    public void SetZipCode(string zip)
    { this.zip = zip; }

    public string GetZipCode()
    { return zip; }
}

//Generic class which can accept either of the above classes
public class MyGenerics<T>
{
    private T selectedValues;
    public MyGenerics(T selectedValues)
    {
        this.selectedValues = selectedValues;
    }
    public String GetZipCode()
    {
        Type typeParameterType = typeof(T);
        var getZipCode = typeParameterType.GetMethod("GetZipCode");
        var val = 

typeParameterType.GetType().GetMethod("GetZipCode").Invoke(typeParameterType, 
 null);
        return val.ToString();
    }
}

//Accessing the class method
public static void Main(string[] args)
    {
        EastCoastStores eastCoastStores = new EastCoastStores();
        eastCoastStores.SetZipCode("12345");
        MyGenerics<EastCoastStores> orderAction = new 
  MyGenerics<EastCoastStores>(eastCoastStores);
        var val = orderAction.GetZipCode();

    }
Massey
  • 1,099
  • 3
  • 24
  • 50
  • 3
    Why are you using reflection? It'd be much simpler if T is a type that is inherited from WestCoastShore and EastCoastShore types... – Alberto Solano May 21 '19 at 21:27
  • 2
    Why are you using generics? If you have two classes with the "same" method, a common interface would seem to be more appropriate. – shf301 May 21 '19 at 21:37
  • 1
    Possible duplicate of [How do I use reflection to call a generic method?](https://stackoverflow.com/questions/232535/how-do-i-use-reflection-to-call-a-generic-method) – LazZiya May 22 '19 at 05:33

1 Answers1

3

I don't understand why you're using generics and reflection. What you're trying to do could be easily achieved using inheritance and polymorphism, without involving reflection that isn't something that should be used carelessly as performance impact could be relevant.

You can follow what I said in the comment, but it'd be too much for an implementation similar to what you posted (several classes with identical methods).

You can use an interface (e.g. ICoastStore) that is implemented by EastCoastStore and WestCoastStore types. Then you don't need to use reflection and the implementation of MyGenerics will be much simpler.

public class EastCoastStores : ICoastStore
{
     private string zip;

     public void SetZipCode(string zip)
     { this.zip = zip; }

     public string GetZipCode()
     { return zip; }
}

public class WestCoastStores : ICoastStore
{
     private string zip;

     public void SetZipCode(string zip)
     { this.zip = zip; }

     public string GetZipCode()
     { return zip; }
}

public interface ICoastStore
{
     void SetZipCode(string zip);

     string GetZipCode();
}

public class MyGenerics
{
     private ICoastStore selectedValues;

     public MyGenerics(ICoastStore selectedValues)
     {
          this.selectedValues = selectedValues;
     }

     public string GetZipCode()
     {
          return selectedValues.GetZipCode();
     }
 }

static void Main(string[] args)
{
      EastCoastStores eastCoastStores = new EastCoastStores();
      eastCoastStores.SetZipCode("12345");
      MyGenerics orderAction = new MyGenerics(eastCoastStores);
      var val = orderAction.GetZipCode();
}
Alberto Solano
  • 7,972
  • 3
  • 38
  • 61
  • Hi Alberto, normally I would have done as you have described. Unfortunately, this is an existing application and I am not allowed to implement inheritance as it would involve a lot of changes. – Massey May 21 '19 at 22:28
  • Hi @Massey. Yeah, I perfectly understand. I've dealt with legacy code myself in the past as well and, based on experience, the only way I found was to refactor the whole project (a lot changes indeed) rather than implementing a small thing to fix a bug or add a feature on top of an existing spaghetti-code repository, because it'd have actually decreased code maintainability by much. As I said, reflection should be used with care. If you proceed with it, your existing application will suffer from performance bottlenecks. Consider if you need to apply more changes in the future. – Alberto Solano May 22 '19 at 07:22