Tell me more ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

In a custom interface for keyed collections I need to implement, I want covariance. So the signature of the interface is IKeyedCollection<TKey, out TValue>. I would also like to include a method similar to TryGetValue in this interface, but covariance on out parameters is not allowed for reasons detailed here. Therefore, the following will not work:

interface IKeyedCollection<TKey, out TValue>
{
    bool TryGetValue(TKey key, out TValue value);
}

But if it worked, it would be used like this:

IKeyedCollection<string, int> someKeyedCollection = ...;
int result;
if (someKeyedCollection.TryGetValue(out result))
{
    ...
}

I am looking for alternatives that do the same: try to get a value from the collection without throwing an exception when it fails, and returning whether it succeeded.


Let me explain my train of thought, and how I arrived at code that does the job.

I imagined that a Result<T> struct might do the trick, but of course the following also does not work as Result<T> is not covariant.

struct Result<T>
{
    T Value { get; }
    bool HasResult { get; }
}

interface IKeyedCollection<TKey, out TValue>
{
    Result<TValue> GetValue(TKey key);
}

I could make a covariant interface IResult<T> but this will cause the return value to be boxed, which is something I would like to avoid:

interface IResult<out T> { ... }

struct Result<T> : IResult<T> { ... }

interface IKeyedCollection<TKey, out TValue>
{
    IResult<TValue> GetValue(TKey key);
}

I could also switch the boolean and the return value parameters. This is not consistent with the way it is done in the .NET Framework, but does solve all previously mentioned problems.

So, the following code actually works. However, I know how the original TryGetValue works and I like how you can put it in an if. You cannot do that here, the syntax is uglier:

interface IKeyedCollection<TKey, out TValue>
{
    TValue GetValue(TKey key, out bool hasResult);
}

IKeyedCollection<string, int> someKeyedCollection = ...;
bool hasResult;
int result = someKeyedCollection.GetValue(out hasResult);
if (hasResult)
{
    ...
}

So, my questions are essentially: to have a TryGetValue or similar method in a covariant interface, do you know of a better way than the above? I think the syntax is uglier and the interface is less usable. Any suggestions or improvements?

share|improve this question
2  
I'm not sure your question is on-topic here, you're not actually asking us to review your code. But it certainly is an interesting question and I think it would fit on SO. – svick Oct 23 '12 at 19:28
I sort of agree with svick, if that last example works it could be argued that this is on topic, but as it stands, and because I don't know the language, it is hard to tell. I'm going to hold off from casting a close vote because I'm just not sure. I would suggest either editing this to clarify the point or moving it to SO. – mseancole Oct 23 '12 at 20:35
The last example works perfectly, but may be not perfect from a code or usability point of view. I really don't see how this question is more applicable to SO, as they want questions that can be answered by facts. And in this question I ask you to review this code. – Virtlink Oct 23 '12 at 22:01
This is probably a good fit for Programmers. – Paul Oct 25 '12 at 1:58

closed as off topic by svick, Brian Reichle, Jeff Vanzella, Trevor Pilley, Paul Oct 25 '12 at 1:58

Questions on Code Review Stack Exchange are expected to relate to code review request within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

Browse other questions tagged or ask your own question.