Reputation: 135
I've got a function that's supposed to add up a bunch of generics, if possible. Otherwise, it returns the value of the last generic it saw. I'd like to loop through my list of generics, try adding them, and then catch an exception if/when they can't be added. I understand that you can't try any opperators on a generic, but I can't understand why. Isn't attempting a certain method that may fail exactly why try catch was build for?
I'm pretty sure there isn't an easy way around this, but if there is, let me know.
Also, the offending code:
T getValueAtTime(float time)
{
T toReturn = officalValue.Value;
float maxValue;
velocities.Sort();
foreach(ValueAtTime<T> toAdd in velocities)
{
if(toAdd.AtTime < time)
{
try
{
toReturn += toAdd.Value;
}
catch(OpperatorUnavailableError err)
{
toReturn = toReturn + toAdd.Value;
}
catch(Exception ex)
{
toReturn = toAdd.Value;
}
}
}
return toReturn;
}
Upvotes: 0
Views: 104
Reputation: 61952
I suppose your T
is a generic parameter to a class/struct which contains your method. Now, I don't know what generic constraints you put on T
, but is not possible to constrain T
to only types which overload the +
operator.
Therefore, this can not be done if T
is a generic parameter.
What types are you using for T
? Simple types like int
, double
and decimal
which have "native" support for +
in the language, or user-defined types which overload the +
operator?
Upvotes: 0
Reputation: 2851
Regardless of c#'s specific prohibition on try-catch in a generic, try catch should not be part of your standard operating method. Your code relies on try-catch in order to overcome an obstacle. That is utterly the wrong use of it. Try-catch is meant to test operations that might fail for uncontrollable (or at least unpredictable) circumstances, and shut down or retry that operation. It is extremely expensive for managed code to catch the error, and it's not meant to be a logical control mechanism.
Edit I did come up with an alternative, based on your comments explaining your question. You are operating on varying game objects. That doesn't require a generic; it requires an interface. If all your objects implement the interface IhasValueAtTime
with a method float getValueAtTime(float time)
, then you can create a function like so float addTwoGetValueAtTimeObjectsSum(IhasValueAtTime item1, IhasValueAtTime item2)
Upvotes: 1
Reputation: 7282
I think the problem is that you are expecting different behaviour from
toReturn += toAdd.Value
and toReturn = toReturn + toAdd.Value
. They are (almost) exactly the same. See this link for further detail.
So when your try throws an exception, your catch will throw the same exception. I think that you would do better to do something like.
T toReturn = officalValue.Value;
float maxValue;
velocities.Sort();
foreach(ValueAtTime<T> toAdd in velocities)
{
if(toAdd.AtTime < time)
{
try
{
toReturn += toAdd.Value;
}
catch(OpperatorUnavailableError err)
{
toReturn = toAdd.Value;
break;
}
}
}
return toReturn;
Upvotes: 0