C# is there a nicer way of writing this? - c#

int uploadsID;
int pageNumber;
int x;
int y;
int w;
int h;
bool isValidUploadID = int.TryParse(context.Request.QueryString["uploadID"], out uploadsID);
bool isValidPage = int.TryParse(context.Request.QueryString["page"], out pageNumber);
bool isValidX = int.TryParse(context.Request.QueryString["x"], out x);
bool isValidY = int.TryParse(context.Request.QueryString["y"], out y);
bool isValidW = int.TryParse(context.Request.QueryString["w"], out w);
bool isValidH = int.TryParse(context.Request.QueryString["h"], out h);
if (isValidUploadID && isValidPage && isValidX && isValidY & isValidW & isValidH)
{
This is an ajax handler, checking all passed params are OK. Is this considered bad, and is there a better way to write this, or is it not that important?

Assuming you're not going to use the individual bool variables elsewhere, you could write that as:
int uploadsID, pageNumber, x, y, w, h;
if (int.TryParse(context.Request.QueryString["uploadID"], out uploadsID) &&
int.TryParse(context.Request.QueryString["page"], out pageNumber) &&
int.TryParse(context.Request.QueryString["x"], out x) &&
int.TryParse(context.Request.QueryString["y"], out y) &&
int.TryParse(context.Request.QueryString["w"], out w) &&
int.TryParse(context.Request.QueryString["h"], out h))
{
}
You may want to extract out int.TryParse(context.Request.QueryString[name], out variable into a separate method, leaving you with something like:
int uploadsID, pageNumber, x, y, w, h;
if (TryParseContextInt32("uploadID", out uploadsID) &&
TryParseContextInt32("page", out pageNumber) &&
TryParseContextInt32("x", out x) &&
TryParseContextInt32("y", out y) &&
TryParseContextInt32("w", out w) &&
TryParseContextInt32("h", out h))
{
}
Alternatively, you could encapsulate all this context data into a new type with a TryParse method, so you'd have something like:
PageDetails details;
if (PageDetails.TryParse(context.Request.QueryString))
{
// Now access details.Page, details.UploadID etc
}
That's obviously more work, but I think it would make the code cleaner.

Yes, start by factoring out your int.TryParse(etc.) into a separate function.
(Possibly over-influenced by F#)
//return a tuple (valid, value) from querystring of context, indexed with key
private Tuple<bool, int> TryGet(HttpContext context, string key)
{
int val = 0;
bool ok = int.TryParse(context.request.QueryString[key], out val);
return Tuple.New(ok, val);
}
Then:
var UploadId = TryGet(context, "uploadID");
//...
if(UploadId.Item1 && etc..)
{
//do something with UploadId.Item2;
To make things slightly clearer, you could
private class ValidValue
{
public bool Valid { get; private set; }
public int Value { get; private set; }
public ValidValue(bool valid, int value)
{
Valid = valid;
Value = value;
}
//etc., but this seems a bit too much like hard work, and you don't get
// equality for free as you would with Tuple, (if you need it)

I would probably go for a formatting like this
int uploadsID, pageNumber, x, y, h;
if (Int32.TryParse(context.Request.QueryString["uploadID"], out uploadsID)
&& Int32.TryParse(context.Request.QueryString["page"], out pageNumber)
&& Int32.TryParse(context.Request.QueryString["x"], out x)
&& Int32.TryParse(context.Request.QueryString["y"], out y)
&& Int32.TryParse(context.Request.QueryString["w"], out w)
&& Int32.TryParse(context.Request.QueryString["h"], out h))
{
...
}
but I don't see anything wrong with your approach.

One thing you can do is to replace this:
int uploadsID;
int pageNumber;
int x;
int y;
int w;
int h;
With this
int uploadsID, pageNumber, x, y, w, h;

try
{
// use Parse instead of TryParse
// all are valid, proceed
}
catch
{
// at least one is not valid
}

You could write a helper that gets rid of the ugly out passing style of TryParse, such as:
public delegate bool TryParser<T>(string text, out T result) where T : struct;
public static T? TryParse<T>(string text, TryParser<T> tryParser)
where T : struct
{
// null checks here.
T result;
return tryParser(text, out result) ? result : new T?();
}
And then (assuming you are only interested in validity):
bool isValid = new [] { "uploadID" , "page", "x", "y", "w", "h" }
.Select(q => context.Request.QueryString[q])
.All(t => TryParse<int>(t, int.TryParse).HasValue);
If you need the individual values:
var numsByKey = new [] { "uploadID" , "page", "x", "y", "w", "h" }
.ToDictionary(q => q,
q => TryParse<int>(context.Request.QueryString[q],
int.TryParse));
bool isValid = numsByKey.Values.All(n => n.HasValue);
This retains pretty much the same information as before, except the fine-grained info needs a lookup rather than a local-variable access.

Related

Use of unassigned local variable in out parameter

I am having a problem with C# giving the "Use of unassigned local variable" compile error. What am I missing?
// returns generic result of a function with error message
// why the function failed
public class Result
{
public bool isSuccess = true;
public string errorMessage = string.Empty;
public static implicit operator bool(Result r)
{
return r.isSuccess;
}
public static Result operator &(Result a, Result b)
{
return !a.isSuccess ? a : b;
}
public static Result operator |(Result a, Result b)
{
if (a.isSuccess)
{
return a;
}
if (b.isSuccess)
{
return b;
}
return new Result
{
isSuccess = false,
errorMessage = $"{a.errorMessage}\nOut{b.errorMessage}"
};
}
public static bool operator false(Result a)
{
return !a.isSuccess;
}
public static bool operator true(Result a)
{
return a.isSuccess;
}
}
static Result Func1(int nIn, out int nOut)
{
nOut = nIn + 1;
return new Result();
}
private static void Main(string[] args)
{
var resultA =
Func1(0, out var a1) &&
Func1(a1, out var a2); // compiles fine
var resultB =
Func1(0, out var b1) &&
Func1(b1, out var b2) &&
Func1(b2, out var b3); // Use of unassigned local variable 'b2'
}
I think this may be a bug in the compiler - I'd personally expect b2 to be definitely assigned there. The spec for definite assignment is pretty hairy though, so I'm not going to try to prove it one way or another right now. It's possible that the rules aren't "clever" enough to work out that the only way that (x && y) is true is if both x and y are evaluated, and so in (x && y) && z, z should be able to rely on both x and y having been evaluated.
However, it's fairly easy to work around, just with an extra pair of parentheses:
var resultB =
Func1(0, out var b1) &&
(Func1(b1, out var b2) && Func1(b2, out var b3));

Array Order different than windows folder explorer [duplicate]

For natural sorting in my application I currently P/Invoke a function called StrCmpLogicalW in shlwapi.dll. I was thinking about trying to run my application under Mono, but then of course I can't have this P/Invoke stuff (as far as I know anyways).
Is it possible to see the implementation of that method somewhere, or is there a good, clean and efficient C# snippet which does the same thing?
My code currently looks like this:
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string psz1, string psz2);
}
public class NaturalStringComparer : IComparer<string>
{
private readonly int modifier = 1;
public NaturalStringComparer() : this(false) {}
public NaturalStringComparer(bool descending)
{
if (descending) modifier = -1;
}
public int Compare(string a, string b)
{
return SafeNativeMethods.StrCmpLogicalW(a ?? "", b ?? "") * modifier;
}
}
So, what I'm looking for is an alternative to the above class which doesn't use an extern function.
I just implemented natural string comparison in C#, perhaps someone might find it useful:
public class NaturalComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int lx = x.Length, ly = y.Length;
for (int mx = 0, my = 0; mx < lx && my < ly; mx++, my++)
{
if (char.IsDigit(x[mx]) && char.IsDigit(y[my]))
{
long vx = 0, vy = 0;
for (; mx < lx && char.IsDigit(x[mx]); mx++)
vx = vx * 10 + x[mx] - '0';
for (; my < ly && char.IsDigit(y[my]); my++)
vy = vy * 10 + y[my] - '0';
if (vx != vy)
return vx > vy ? 1 : -1;
}
if (mx < lx && my < ly && x[mx] != y[my])
return x[mx] > y[my] ? 1 : -1;
}
return lx - ly;
}
}
http://www.interact-sw.co.uk/iangblog/2007/12/13/natural-sorting seems to be what you're looking for.
(and no, there is no managed equivalent to StrCmpLogicalW built into .NET)
I used regular expression to remove special characters. then casting to int. then i compared integers.
input :
List input = new List{ "6.04","6.01","6.03","6#04" };
Expected Output:
6.01
6.03
6.04
6#04
var output = input.OrderBy(s => s, new NaturalStringComparer());
foreach (var sort in output)
{
Console.WriteLine(sort);
}
public struct NaturalStringComparer : IComparer
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int lx = x.Length, ly = y.Length;
int a = int.Parse(System.Text.RegularExpressions.Regex.Replace(x, #"\D+", ""));
int b = int.Parse(System.Text.RegularExpressions.Regex.Replace(y, #"\D+", ""));
return a.CompareTo(b);
}
}
If you're running on Windows XP or newer, you can PInvoke to the shell function StrCmpLogicalW:
public static int StrCmpLogical(String s1, String s2)
{
if (String.IsNullOrEmpty(s1) && !String.IsNullOrEmpty(s2))
return 1; //empty s1 comes after s2
else if (String.IsNullOrEmpty(s2) && !String.IsNullOrEmpty(s1))
return -1; //non-empty string comes before empty
return SafeNativeMethods.StrCmpLogicalW(s1, s2);
}
And then the internal unsafe class:
/// <summary>
/// This class suppresses stack walks for unmanaged code permission.
/// (System.Security.SuppressUnmanagedCodeSecurityAttribute is applied to this class.)
/// This class is for methods that are safe for anyone to call.
/// Callers of these methods are not required to perform a full security review to make sure that the
/// usage is secure because the methods are harmless for any caller.
/// </summary>
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
internal static extern Int32 StrCmpLogicalW(string psz1, string psz2);
}

Sorting an Arraylist of strings on a portion of each string, delimited by a character

I'm trying to sort an ArrayList of strings (not in int).
Given:
f.e.
[0] 23,24
[1] 12,33
[2] 37,11
Arraylist.Sort should give back (sorted by the last number ascending):
[0] 37,11
[1] 23,24
[2] 12,33
Having this so far:
public class Point
{
public int i, j;
public Point(int i, int j)
{this.i = i; this.j = j;}
public string ToString()
{return i + "," + j;}
}
public class SList
{
public static void Main()
{
ArrayList Slist = new ArrayList();
Random Generate = new Random();
for (int i = 0; i < 3; i++)
{
Point p = new Point(Generate.Next(40), Generate.Next(40));
Slist.Add(p.ToString());
}
Slist.Sort();
}
}
I'm not 100% sure if you have an array of strings or if they are split already, but you can create a custom comparer and do something like this perhaps. Make clearer what you want so that people can help you better.
public class MyCustomComparer : IComparer<string>
{
public int Compare(string x, string y)
{
var xIntValues = x.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
var yIntValues = y.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();
for(var i = 0; i < Math.Min(xIntValues.Count(), yIntValues.Count()); ++i)
if (xIntValues[i] != yIntValues[i])
return xIntValues[i] - yIntValues[i];
return xIntValues.Count() - yIntValues.Count();
}
}
Then use it like this where your array elements contain strings like "37, 11"
Array.Sort(myArray, MyCustomComparer);
Sort of odd to be using an ArrayList after c# 1.0, but if you have one for legacy reasons, you can create your own non-generic custom comparer, like so:
public class CustomComparer : IComparer<string>, IComparer {
#region IComparer<string> Members
int? ExtractNumber(string str)
{
int index = str.LastIndexOf(',');
if (index < 0)
return null;
var subStr = str.Substring(index+1);
int result;
if (int.TryParse(subStr, out result))
return result;
return null;
}
// Return x - y
public int Compare(string x, string y)
{
#if false
Given: f.e.
[0] 23,24
[1] 12,33
[2] 37,11
Arraylist.Sort should give back (sorted by the last number ascending):
[0] 37,11
[1] 23,24
[2] 12,33
#endif
var xVal = ExtractNumber(x);
var yVal = ExtractNumber(y);
if (!xVal.HasValue && !yVal.HasValue)
return x.CompareTo(y);
else if (!xVal.HasValue)
return 1;
else if (!yVal.HasValue)
return -1;
int cmp = xVal.Value.CompareTo(yVal.Value);
if (cmp != 0)
return cmp;
return x.CompareTo(y);
}
#endregion
#region IComparer Members
public int Compare(object x, object y)
{
if (object.ReferenceEquals(x, y))
return 0;
string xStr = x as string;
string yStr = y as string;
if (xStr == null && yStr == null)
return 0; // NO IDEA
else if (xStr == null)
return 1;
else if (yStr == null)
return -1;
else return Compare(xStr, yStr);
}
#endregion
}
The following code implements IComparable on your class. It sorts on y in ascending order:
public class Point : IComparable<Point>
{
public int x;
public int y;
public Point(int x, int y)
{
this.x = x;
this.y = y;
}
public string ToString()
{
return x + "," + y;
}
public int CompareTo(Point other)
{
return this.y.CompareTo(other.y);
}
}
You can now use ArrayList.Sort() to achieve the order you need.
The easiest way to do this would be by stepping away from your non-generic list:
var sortedList = list.Cast<string>().OrderBy(x => x.Split(',')[1]);
The code is self-explanatory.
Using this as input:
var list = new ArrayList();
list.Add("23,24");
list.Add("12,33");
list.Add("37,11");
Yields this as output:
37,11
23,24
12,33

Create an array that points to only part of another array?

I have a huge array that contains reference type elements, and I want to create a lot of other arrays that essentially just point to specific parts of that one big array.
In other words, I want to create "indexers" or "pointers with lengths".
In C++ it's easy to do so using pointers and for each pointer assign a length, for example create a struct which contains a pointer with a length.
How can I achieve this in C#/.NET?
The whole point is to avoid copying anything, I just want pointers to specific parts in an array that already exists in memory.
Any ideas?
Jon's suggestion of using ArraySegment<T> is likely what you want. If however you are wanting to represent a pointer to the interior of an array, the way you can in C++, here's some code for that. No warranty is expressed or implied, use at your own risk.
This code does not track the "length" of the interior pointer in any way, but it is quite easy to add that feature if you want.
internal struct ArrayPtr<T>
{
public static ArrayPtr<T> Null { get { return default(ArrayPtr<T>); } }
private readonly T[] source;
private readonly int index;
private ArrayPtr(ArrayPtr<T> old, int delta)
{
this.source = old.source;
this.index = old.index + delta;
Debug.Assert(index >= 0);
Debug.Assert(index == 0 || this.source != null && index < this.source.Length);
}
public ArrayPtr(T[] source)
{
this.source = source;
index = 0;
}
public bool IsNull()
{
return this.source == null;
}
public static bool operator <(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index < b.index;
}
public static bool operator >(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index > b.index;
}
public static bool operator <=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index <= b.index;
}
public static bool operator >=(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index >= b.index;
}
public static int operator -(ArrayPtr<T> a, ArrayPtr<T> b)
{
Debug.Assert(Object.ReferenceEquals(a.source, b.source));
return a.index - b.index;
}
public static ArrayPtr<T> operator +(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, +count);
}
public static ArrayPtr<T> operator -(ArrayPtr<T> a, int count)
{
return new ArrayPtr<T>(a, -count);
}
public static ArrayPtr<T> operator ++(ArrayPtr<T> a)
{
return a + 1;
}
public static ArrayPtr<T> operator --(ArrayPtr<T> a)
{
return a - 1;
}
public static implicit operator ArrayPtr<T>(T[] x)
{
return new ArrayPtr<T>(x);
}
public static bool operator ==(ArrayPtr<T> x, ArrayPtr<T> y)
{
return x.source == y.source && x.index == y.index;
}
public static bool operator !=(ArrayPtr<T> x, ArrayPtr<T> y)
{
return !(x == y);
}
public override bool Equals(object x)
{
if (x == null) return this.source == null;
var ptr = x as ArrayPtr<T>?;
if (!ptr.HasValue) return false;
return this == ptr.Value;
}
public override int GetHashCode()
{
unchecked
{
int hash = this.source == null ? 0 : this.source.GetHashCode();
return hash + this.index;
}
}
public T this[int index]
{
get { return source[index + this.index]; }
set { source[index + this.index] = value; }
}
}
Now we can do stuff like:
double[] arr = new double[10];
var p0 = (ArrayPtr<double>)arr;
var p5 = p0 + 5;
p5[0] = 123.4; // sets arr[5] to 123.4
var p7 = p0 + 7;
int diff = p7 - p5; // 2
It sounds like you're looking for something like ArraySegment<T>. Contrary to my earlier thoughts, it does have an indexer and implement IEnumerable<T> etc - it's just done with explicit interfaces.
Sample code:
using System;
using System.Collections.Generic;
static class Test
{
static void Main()
{
string[] original = { "The", "quick", "brown", "fox", "jumped", "over",
"the", "lazy", "dog" };
IList<string> segment = new ArraySegment<string>(original, 3, 4);
Console.WriteLine(segment[2]); // over
foreach (var word in segment)
{
Console.WriteLine(word); // fox jumped over the
}
}
}
EDIT: As noted in comments, ArraySegment<T> is only really "fully functional" in .NET 4.5. The .NET 4 version doesn't implement any interfaces.
You could use LINQ:
yourArray.Skip(startIndex).Take(numberToTake)
The query is lazily evaluated.

How, if possible, can you pass in a C# Property to be used like a method?

I know Func<> is used to pass a method that has a return value to be used inside another method. I know Action<> is used to pass a method that does not have a return value to be used inside another method. Is there a way to pass in a property so it's get/set can be used inside another method?
For example, here is a method that uses Func<>:
public bool RangeCheck (int minVal, int maxVal, Func<< int, int >> someMethod)
{
bool retval = true;
try
{
for (int count = min; count <= max; count++)
{
int hello = someMethod(count);
}
}
catch
{
retval = false;
}
return retval;
}
What I am looking for is something like this:
public bool RangeCheck(int min, int max, Prop<< int >> someProperty)
{
bool retval = true;
try
{
for (int count = min; count <= max; count++)
{
someProperty = count;
}
}
catch
{
retval = false;
}
return retval;
}
Is there anything out there like this? I can't find anything. This would be very useful. Thanks.
Could you use a lambda as a wrapper?
MyClass myClass = new MyClass();
bool val = RangeCheck(0, 10, () => myClass.MyProperty);
If you're looking to do both, you would make two lambdas, one for set, and one for get.
bool val = RangeCheck(0, 10, () => myClass.MyProperty, (y) => myClass.MyProperty = y);
My syntax is probably off, but I think this gives the idea.
Not that I know of. You could try using reflection and pass the object along with the corresponding PropertyInfo object of the property you want to get the value of. You then call PropertyInfo's SetValue function to assign a value to it (assuming it's read/write, of course).
public void SetMyIntValue()
{
SetPropertyValue(this, this.GetType().GetProperty("MyInt"));
}
public int MyInt { get; set; }
public void SetPropertyValue(object obj, PropertyInfo pInfo)
{
pInfo.SetValue(obj, 5);
}
Why not simply make it a ref argument?
public bool RangeCheck(int min, int max, ref int someProperty)
You can now set the value of someProperty inside the method.
And call it like so:
RangeCheck(min, max, ref myProperty);
You could use a Func like this Func<int, T>
void Main()
{
var sc = new SimpleClass();
var result = RangeCheck(0, 10, x => sc.Value = x );
System.Console.WriteLine(result);
System.Console.WriteLine(sc.Value);
}
public class SimpleClass
{
public int Value { get; set; }
}
public bool RangeCheck<T>(int minVal, int maxVal, Func<int, T> someMethod)
{
bool retval = true;
try
{
for (int count = minVal; count <= maxVal; count++)
{
//someMethod(count); //is not a range check,
//Did you mean
someMethod(count - minValue);
}
}
catch
{
retval = false;
}
return retval;
}

Categories