VS Designer error: GenericArguments[0], 'X' on 'Y' violates the constraint of type parameter 'Z'
Asked Answered
I

2

13

I am trying to create forms that inherit from a "generic" base class where the generic argument of that base class has a constraint that it must implement one of my interfaces.

It compiles and runs just fine. My problem is with the Visual Studio designer. It will open the form fine until I rebuild the project, after which it then reports the error below when trying to view the form designer until such time as I either restart Visual Studio, or remove the custom interface constraint in the base class.

GenericArguments[0], 'InterfaceInBaseClassProblem.TestEntity', on 'InterfaceInBaseClassProblem.BaseWindowClass`1[EntityType]' violates the constraint of type 'EntityType'.

Step 1: Create an interface

namespace InterfaceInBaseClassProblem
{
    public interface ITestInterface
    {
        void Func1();
    }
}

Step 2: Create a class that implements the interface

namespace InterfaceInBaseClassProblem
{
    public class TestEntity : ITestInterface
    {
        public void Func1()
        {
        }
    }
}

Step 3: Create a generic base class Form that requires a generic parameter constrained to require an implementation of the interface we created

using System.Windows.Forms;
namespace InterfaceInBaseClassProblem
{
    public class BaseWindowClass<EntityType> : Form where EntityType : ITestInterface
    {
    }
}

Step 4: Now create a new form that inherits from our Generic Base Form and uses the TestEntity class as the parameter

namespace InterfaceInBaseClassProblem
{
    public partial class Form1 : BaseWindowClass<TestEntity>
    {
        public Form1()
        {
            InitializeComponent();
        }
    }
}

Step 5: Save your project and test for the following behaviour that I am trying to work around or solve:

a) Close Visual Studio
b) Open Visual Studio
c) Open the Form1 class to view its designer and confirm its working
d) Close the Form1 designer you just opened
e) Rebuild the project
f) Open the Form1 class to view the error I have reported.
g) Either restart Visual Studio, or comment out the "where EntityType : ITestInterface" constraint we included with step 3 and rebuild to see it start working again

Additional Notes:

  • I have tested in VS2015 and 2017 with the same results
  • I have tested on multiple development machines
  • My need for this design is in the base class and various additional functions / roles it will perform that require a generic "EntityType" and require it can perform the actions I add to my custom interface(s). These generic functions will be used by all forms I declare to inherit from this base class.
Ingeingeberg answered 30/1, 2017 at 8:49 Comment(6)
have you reported it?Pleo
Yes, the response was: Thanks for reporting this problem. After careful evaluation of the problem impact and severity we are closing this problem as low priority. We understand that this might not be an ideal resolution for you etc etc.Ingeingeberg
@Ingeingeberg Did you solve this problem ? I have the same problem but I can't find the solution.Rillings
I have not been able to solve this problem. I am still forced to restart Visual Studio frequently. Compiling the project after having the designer open even once means that I need to restart Visual Studio before I can use the designer a second time.Ingeingeberg
@Ingeingeberg I assume this is still an issue on your end? Is there perhaps a link to the issue you reported that we could upvote?Doctrinal
Here is a link to the reported issue and answer: developercommunity.visualstudio.com/t/…Ingeingeberg
J
6

In case Microsoft sees this, I'm getting a similar issue. Confirmed in VS2015. I have 4 forms:

public class BaseForm : Form
{
    public BaseForm() {...}
}

public class BaseSubForm<T> : Form where T : BaseForm
{
    public SubForm(T f) {...}
    public InitForm(T f) {...}
}

public partial class TestForm : BaseForm
{
    TestSubForm sf;

    public TestForm()
    {
        ...
        sf = new TestSubForm(this);
    }
}

public partial class TestSubForm : BaseSubForm<TestForm>
{
    public TestSubForm(TestForm f) : base(f)
    {
        InitializeComponent();
    }
}

If I build this, it'll run, but TestSubForm won't display in the designer. However, if I remove the argument from BaseSubForm's constructor...

...
public SubForm() {...}
...
sf = new TestSubForm();
...
public TestSubForm(TestForm f)
...

I can restart Visual Studio, build, and it'll display just fine. I can get by on passing that argument in InitForm, my 2nd stage constructor, but it's irritating I need 2 constructors.

Designer seems to hate classes of type Subclass : BaseClass<Generic>

Jeffereyjefferies answered 27/4, 2018 at 22:37 Comment(0)
M
0

Workaround(vs2019):
.. if functionality in implementing interface is not paramount, you can afford to leave it permanently off in DEBUG mode

//#define USEGENERCIS // comment to use designer or un-comment to include interface constraint
#if !DEBUG // .. safeguard for RELEASE build
#define USEGENERCIS
#endif
//.. then:
public class BaseView<T> : Form, IViewFor<T>, IView where T : class
#if USEGENERCIS // conditional include
, IBaseViewModel
#endif

But still need to open form in designer TWICE after rebuild
First "View Designer" fails with:
"The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: X --- The base class 'Y`1' could not be loaded. Ensure the assembly has been referenced and that all projects have been built."

Martinsen answered 27/11, 2021 at 17:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.