Hi Tobias,
Unfortunately there is a much deeper issue here with tests like this one. At some root level of a test framework, it must be possible to uniquely identify a test within a discovery or execution run. This is because data is collected from the test that needs to be organised across multiple test runs, and NCrunch also needs to be able to specifically tell the test framework which tests to execute in a given batch.
When the only element of a test case that can distinguish it from any other test case happens to be user type parameter that does not override .ToString(), there is no physical way to tell the test apart - not just in the UI of any runner, but also down in the runner and the test framework.
It's easy to see how this is less important when using a test runner that only runs all the tests end-to-end. In this context, there is no need to correlate data across test runs, or even selectively identify which tests are to be executed - you just run them all. This is why your tests are still able to run with many of the standard tools. Internally, NUnit uses sequentially generated IDs for every test inside an assembly. This allows it to uniquely identify tests, but only within the scope of a single session - if the assembly is changed, the identifiers are invalidated and all data must be thrown away.
Xunit actually has a similar problem and it introduces a level of handling to prevent these tests from causing problems. When it detects test cases that rely on a user defined type, it will immediately 'roll them up' into a single physical test representing all test cases. This allows both the framework and the runner to function without unexpected issues, but it does in some ways defeat the point of creating granular test cases with individual pass/fail results.
So basically what we're dealing with here is a technical constraint with no ideal workaround. All I can advise is that you design your tests accordingly.