-
Notifications
You must be signed in to change notification settings - Fork 45
Description
Issue: Hard-Coded Assumption in Sheet.cs Line 76
In Sheet.cs, line 76, there's a hard-coded assumption about generic type positions:
var referenceRowType = node.ValueType.GenericTypeArguments[1];Problem
This works fine for Sheet<TRow> (aka Sheet<string, TRow>) scenarios where TRow is the second generic type argument, but fails when users declare more complex subclasses. For example:
// References to rows in this Sheet type work because TRow is the second argument (Sheet<string, TRow>)...
public class FooSheet : Sheet<TRow> { /*...*/ }
// ... but not here because TRow isn't in position [1]!
public class FooSheet<TBar, TBaz, TRow> : Sheet<TRow> { /*...*/ }
// ... but this one is OK again
public class FooSheet<TBar, TRow, TBaz> : Sheet<TRow> { /*...*/ }Because of the [1] assumption, TRow must always be at index [1]. That means that users are restricted in how they structure their types. If they're not careful, they'll experience broken references to rows in their custom subclasses! I hit this issue myself just now, and it took me a while to track this one down.
Suggested Solution
Instead of hard-coding the index, could try dynamically searching for the correct type:
// Note: TValue is the row value type in this code block, in Sheet.cs (`Sheet<TKey, TValue>`)
var referenceRowType = node.ValueType.GenericTypeArguments.FirstOrDefault(x => typeof(TValue).IsAssignableFrom(x));
if (referenceRowType == null)
{
context.Logger.LogError($"Failed to find reference row type {TValue.Name} in {node.ValueType.Name} GenericTypeArguments");
continue;
}This way, it tries to find the correct type dynamically. Note that the code above avoids a potential exception by using FirstOrDefault, hence the extra null check. Also, could go with (x => typeof(TValue) == x) if you'd prefer an exact type match.
I’m happy to submit a PR with the above fix or, if you're not digging that change, let's discuss another approach. If a PR is welcome, would you prefer that I add some tests as well, or do you just want the patch with the fix?
Let me know if you'd like any further adjustments!