C# Generic: How to properly wrap method

Question

I am a newer in programming and I have a question about Generic. Here is structure of my small program:

public enum FieldsA
{
    A,
    B,
    C
}

public enum FieldsB
{
    A,
    B,
    C
}

public abstract class Page
{

}

public abstract class BasePage<T> : Page where T : struct, IComparable
{
    public void Update()
    {
        // code
    }
}

public class ClassA : BasePage<FieldsA>
{

}

public class ClassB : BasePage<FieldsB>
{

}

public class MainClassA
{
    private ClassA _classA;

    public MainClassA(ClassA classA)
    {
        _classA = classA;
    }


    public void Method()
    {
        _classA.Update();            
    }
}

public class MainClassB
{
    private ClassB _classB;

    public MainClassB(ClassB classB)
    {
        _classB = classB;
    }

    public void Method()
    {
        _classB.Update();           
    }
}

I want to ask how properly create some static method, where I wrap Update() method. I tried something like this:

public static class Helper
{        
    public static void Update<T>(BasePage<T> page)
    {
        page.Update();
    }
}

and replace content in Method() to:

public class MainClassB
{
    private ClassB _classB;

    public MainClassB(ClassB classB)
    {
        _classB = classB;
    }

    public void Method()
    {
        Helper.Update(_classB);          
    }
}

(same for MainClassA) but it does not work -> Compilation error: The Type T must be a non-nullable value type in order to use it as parameter T in the generic type or method BasePage. Thanks for tips and help.


Show source
| generics   | c#   | inheritance   | static   2016-12-29 14:12 2 Answers

Answers ( 2 )

  1. 2016-12-29 14:12

    Your problem is where statement:

    public abstract class BasePage<T> : Page where T : struct, IComparable
    

    You need to have same thing in your static class

    public static class Helper
    {        
        public static void Update<T>(BasePage<T> page) where T : struct, IComparable
        {
            page.Update();
        }
    }
    

    because BasePage<T> requires it.

    Possibly enough would be where T: class as well, at least until T is not used in a way that it requires be struct or implementation if IComparable interface.

    Please also refer that page: https://msdn.microsoft.com/en-us/library/bb384067.aspx where is a bit more information about where clause

  2. 2016-12-29 14:12

    What you are trying to do, looks a lot like a visitor pattern to me:

    When you take a look at the pattern, probably you can find some similarities to your sample code : BasePage<T> would be the abstract element with two concrete implementations ClassA and ClassB. The public interface of BasePage<T>.Update() most likely will be the Visit() method.

    Sticking with design patterns in OO allows you to focus on writing your functions instead of worrying about good class design. It also can save you from some trouble, e.g. unit testing static functions. But, use the right pattern for the right situations.

    When you scroll down the dofacotry link, you can find a few C# example implementations.

◀ Go back