Reputation: 1
EDIT: Originally, this post's example had dealt with hash codes, so you will see some comments using param.GetHashCode(), rather than (1+param). To get more to the point, I have changed the functions to calculate one plus the absolute value of some number.
Let's say that I want to create a function that calculates the absolute value of some integer (without using Math.Abs). I could write something similar to:
int absoluteValueOfOnePlus(int param)
{
int onePlusParam= 1 + param;
return ((onePlusParam> 0) ? (onePlusParam) : (-onePlusParam) );
}
I'm looking to limit the scope of onePlusParm to within the ternary statement--something similar to:
int absoluteValueOfOnePlus(intparam)
{
return (((int onePlusParam = 1 + param) > 0) ? (onePlusParam) : (-onePlusParam) );
}
I understand that this is not valid C#, but it proves a good example for what I'm trying to perform--create some variable which exists only in the scope of a ternary operator.
Upvotes: 0
Views: 276
Reputation: 22433
Besides just creating a new block you could also use the built in Absolute value function Math.Abs(...)
or define your own lambda/function;
...built in ...
public static int hash(string param)
{
return Math.Abs(param.GetHashCode());
}
... lambda ...
static Func<int, int> abs = i => i > 0 ? i : -i;
public static int hash(string param)
{
return abs(param.GetHashCode());
}
... static function ...
static int Abs(int i)
{
return i > 0 ? i : -i;
}
public static int hash(string param)
{
return Abs(param.GetHashCode());
}
Upvotes: 0
Reputation: 7618
And my attempt
static int positiveHash(string param)
{
return new List<string>() {param}.Select(s => s.GetHashCode()).Select(i => (i > 0) ? (i) : (-i)).Single();
}
(Of course your code (and mine) is bad,you need to split your method into 2 smaller ones)
and the updated question
static int absoluteValueOfOnePlus(int intparam)
{
return new List<int> { intparam }.Select(n => n + 1).Select(i => (i > 0) ? (i) : (-i)).Single();
}
Upvotes: 0
Reputation: 20772
You could substitute having a data variable (i
) in scope to having a function variable in scope. The advantage is a function is more likely to be written only once and not likely to be misused.
int positiveHash(string param)
{
Func<int, int> absoluteValue = i => (i > 0) ? i : -1;
return absoluteValue(param.GetHashCode());
}
Upvotes: 1
Reputation: 5165
I would simply write:
int GetPositiveHash(string param)
{
return Math.Abs(param.GetHashCode());
}
or
int GetPositiveHash(string param)
{
int hashCode = param.GetHashCode();
return Math.Abs(hashCode);
}
The aids readability, maintainability and more importantly in this case avoid premature optimization which is the root of all evil.
If you are really worried about performance then profile you code and see where your biggest bottlenecks are. I'd be surprised if GetPosiitiveHash()
is causing the biggest bottleneck.
You might like to have a look at the .Net Framework source code for String.GetHashCode()
. You'll see that a ternary operator is going to have quite a minimal saving compared what going on inside the GetHashCode()
method.
It's worth remembering:
The full version of the quote is "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." and I agree with this. Its usually not worth spending a lot of time micro-optimizing code before its obvious where the performance bottlenecks are.
from The fallacy of premature optimization
Upvotes: 1
Reputation: 11621
The parts of a ternary expression are expressions. If the language designers were to allow what you're asking for, they would probably do it for all expressions rather than just for ternary expressions. You would then also be able to do if ((int n = foo()) != 0) bar(n);
.
In C#, declarations are statements, not expressions. So the answer is no, you can't do this. However, the for
statement can take a declaration, so the closest you can get to a single statement is this:
for (int i = param.GetHashCode();;)
return (i > 0) ? i : -i;
which is technically a single statement, albeit a compound one, and on two lines. But that looks awful code and I wouldn't write it like that.
If your main concern is minimizing the scope of i
, then use a small scope for it:
int positiveHash(string param)
{
// Some statements here...
// ...
// Start a small scope
{
int i = param.GetHashCode();
if (...)
return ((i > 0) ? (i) : (-i) );
}
// Some more C# statements here.
// i is out of scope here.
}
Upvotes: 3