I am implementing the next function:
private bool CheckRelativeIncrease(T pVal1, T pVal2, out T pFluctuation, int x)
where I compare if pVal2 has increased more than a "x%" over pVal1. I am using Generics to make the function work with int, short... I am using MiscUtils.Operator but the problem is that I can't mix known and unknown types. The following code doesn't work:
bool increased = false;
int comparer = Comparer.Default.Compare(pVal1, pVal2);
pFluctuation = Operator<T>.Zero;
if (comparer > 0) {
int factor = (int)(1 + (x / 100));
pFluctuation = Operator.Multiply(factor, pVal2);
comparer = Comparer.Default.Compare(pVal1, pFluctuation);
if (comparer >= 0)
increased = true;
}
return increased;
"Operator.Multiply" gives me an error because 'factor' has not the same type as 'pVal2'.
Any ideas?
Thanks in advance,
Silvia
I don't believe we currently support operators on mixed types - but if you look at the code in Operator<T> it should be pretty easy to adapt it. Feel free to send me a patch :)
Basically you'll need an Operator<T1, T2, TResult> which looks like Operator<TValue, TResult> except it uses different types for the different inputs and outputs. You'll need to specify what the expected result type is, of course - if you're multiply T by int, would you expect the result to be int, T or something else?
If you're using C# 4 and .NET 4, you may want to consider using dynamic typing instead...
There is also two-type multiply operation which you can use, according to this documentation:
public static TArg1 MultiplyAlternative(TArg1 value1, TArg2 value2)
Write another function to cast one type as another type. Make a nested call to that function within your code and problem solved.
Related
I've got a enum type defined in my C# code that corresponds to all possible values for the NetConnectionStatus field in Win32_NetworkAdapter WMI table, as documented here.
The documentation shows that the integers 0 through 12 each have a unique status name, but then all integers between 13 and 65,535 are lumped into one bucket called "Other." So here's my code:
[Serializable]
public enum NetConnectionStatus
{
Disconnected = 0,
Connecting = 1,
Connected = 2,
Disconnecting = 3,
HardwareNotPresent = 4,
HardwareDisabled = 5,
HardwareMalfunction = 6,
MediaDisconnected = 7,
Authenticating = 8,
AuthenticationSucceeded = 9,
AuthenticationFailed = 10,
InvalidAddress = 11,
CredentialsRequired = 12,
Other
}
This works fine for the values that are not Other. For instance, I can do this:
var result = (NetConnectionStatus) 2;
Assert.AreEqual(NetConnectionStatus.Connected, result);
But for anything in that higher numeric range, it doesn't work so great. I would like it if I could do this:
var result = (NetConnectionStatus) 20;
Assert.AreEqual(NetConnectionStatus.Other, result);
But right now that result variable gets assigned the literal value 20 instead of Other. Is there some out-of-the-box way of accomplishing this, something akin to Parse() but for integers instead of strings, or perhaps some special attribute I'm unaware of? I would prefer to not write my own wrapper method for this if there is already a good way to accomplish this.
If you have a string value, then the closest thing I can think of is to use Enum.TryParse:
NetConnectionStatus result;
if (Enum.TryParse(stringValue, out result) == false)
result = NetConnectionStatus.Other;
For an integer value that you're casting, you can use:
result = (NetConnectionStatus)integerValue;
if (Enum.GetValues(typeof(NetConnectionStatus)).Contains(result) == false)
result = NetConnectionStatus.Other;
Not really ideal, but in C# enums aren't much more than fancy names for integral values, so it's valid to stuff an integer value not in the defined values of the enums into a value of that enum type.
This solution will handle negative numbers, or cases where you have gaps in your enum values more elegantly than doing numerical comparisons.
it would be nice but no. How about
var result = (NetConnectionStatus) 20;
Assert.IsTrue(result >= (int)NetConnectionStatus.Other);
.NET does not such thing as a "any other" enumeration value bucket. Technically, enumeration (enum) is a pretty set of named constants of some underlying type (which is one of following: sbyte, short, int, long and their unsigned counterparts). You can cast an enum value to/from a corresponding type without any losses, as in this example:
enum TestEnum:int // Explicitly stating a type.
{
OnlyElement=0
}
class Program
{
static void Main(string[] args)
{
// Console.WriteLine implicitly calls ToString of the TestEnum.OnlyElement.
Console.WriteLine("OnlyElement == {0}", TestEnum.OnlyElement);
//TestEnum.OnlyElement equals to 0, as demonstrated by this casting:
Console.WriteLine("(int)OnlyElement == {0}", (int)TestEnum.OnlyElement);
//We can do it in reverse...
Console.WriteLine("(TestEnum)0 == ",(TestEnum)0);
// But what happens when we try to cast a value, which is not
// representable by any of enum's named constants,
// into value of enum in question? No exception is thrown
// whatsoever: enum variable simply holds that value, and,
// having no named constant to associate it with, simply returns
// that value when attempting to "ToString"ify it:
Console.WriteLine("(TestEnum)5 == {0}", (TestEnum)5); //prints "(TestEnum)5 == 5".
Console.ReadKey();
}
}
I'd like to repeat it again, enum in .NET is simply a value of the underlying type with some nice decorations like overriden ToString method and flags checking (look here or here if you want to know more about flags). You cannot have an integer with only 14 values like "0..12 and everything else", and so you cannot have such enum. In your example, NetConnectionStatus.Other simply receives single literal value (I assume it would most probably be '13', as the next available positive value of underlying type - however it actually depends on the compiler) as any other enumeration constant would do if not specified explicitly - and, obviously, it does not become a bucket.
However, there are options to achieve simple equation checks for integers/bytes/shorts/longs - and enums alike. Consider this extension method:
static bool IsOther(this NetConnectionStatus A)
{
return (A < (NetConnectionStatus)0) || (A > (NetConnectionStatus)12);
}
Now you can have a simple assertion like this:
var result = (NetConnectionStatus)10;
Trace.Assert(result.IsOther()); //No assertion is triggered; result is NetConnectionStatus.AuthenticationFailed
and
var result = (NetConnectionStatus)20;
Trace.Assert(result.IsOther()); //Assertion failed; result is undefined!
(Of course you can replace IsOther method with IsNotOther, overload it and pretty much anything else you could do with a method.)
Now there is one more thing. Enum class itself contains a method called IsDefined, which allows you to avoid checks for specific enum's value boundaries (<0, >12), therefore preventing unwanted bugs in case enum values would ever be added/removed, at the small performance cost of unboxing and checking each value in enum for a match (I'm not sure how this works under the hood though, I hope these checks are optimized). So your method would look like this:
static bool IsOther(NetConnectionStatus A)
{
return !Enum.IsDefined(typeof(NetConnectionStatus), A);
}
(However, concluding from enum's name, it seems like you want to make a network application/server, and for these performance might be of very great importance - but most probably I'm just being paranoid and this will not be your application's bottleneck. Stability is much more of concern, and, unless you experience real troubles with performance, it is considered to be much better practice to enable as much stability&safety&portability as possible. Enum.IsDefined is much more understandable, portable and stable than the explicit boundaries checking.)
Hope that helps!
Thanks everyone for the replies. As confirmed by all of you, there is indeed no way to do this out-of-the-box. For the benefit of others I thought I'd post the (custom) code I ended up writing. I wrote an extension method that utilizes a custom attribute on the enum value that I called [CatchAll].
public class CatchAll : Attribute { }
public static class EnumExtensions
{
public static T ToEnum<T, U>(this U value) where T : struct, IConvertible where U : struct, IComparable, IConvertible, IFormattable, IComparable<U>, IEquatable<U>
{
var result = (T)Enum.ToObject(typeof(T), value);
var values = Enum.GetValues(typeof(T)).Cast<T>().ToList();
if (!values.Contains(result))
{
foreach (var enumVal in from enumVal in values
let info = typeof(T).GetField(enumVal.ToString())
let attrs = info.GetCustomAttributes(typeof(CatchAll), false)
where attrs.Length == 1
select enumVal)
{
result = enumVal;
break;
}
}
return result;
}
}
So then I just have to apply that [CatchAll] attribute to the Other value in the enum definition. Then I can do things like this:
int value = 13;
var result = value.ToEnum<NetConnectionStatus, int>();
Assert.AreEqual(NetConnectionStatus.Other, result);
And this:
ushort value = 20;
result = value.ToEnum<NetConnectionStatus, ushort>();
Assert.AreEqual(NetConnectionStatus.Other, result);
I am used to using functions that return a single value "in-line" like so:
Label1.Text = firstString + functionReturnSecondString(aGivenParameter);
Can this be done for a function that returns two values?
Hypothetical example:
label1.Text = multipleReturnFunction(parameter).firstValue
I have been looking into returning more than one value and it looks like the best options are using a tuple, struct, or an array list.
I made a working function that retuns a struct. However the way I got it to work I need to first call the function, then I can use the values. It doesn't seem possible to make it happen all on the same line without writing another function.
multipleReturnFunction(parameter);
Label1.Text = firstString + classOfStruct.secondString;
I haven't made a function that returns a tuple or array list yet, so I'm not sure. Is it possible to call those functions and reference the return values "inline"?
I appreciate your feedback.
I have a grotty hack for exactly this type of scenario - when you want to perform multiple operations on the return value without defining an extra variable to store it:
public static TResult Apply<TInput, TResult>(this TInput input, Func<TInput, TResult> transformation)
{
return transformation(input);
}
... and here's the reason it came about in the first place:
var collection = Enumerable.Range(1, 3);
// Average reimplemented with Aggregate.
double average = collection
.Aggregate(
new { Count = 0, Sum = 0 },
(acc, i) => new { Count = acc.Count + 1, Sum = acc.Sum + i })
.Apply(a => (double)a.Sum / (double)a.Count); // Note: we have access to both Sum and Count despite never having stored the result of the call to .Aggregate().
Console.WriteLine("Average: {0}", average);
Needless to say this is better suited for academic exercises than actual production code.
Alternatively, use the ref or they out keyword.
Example:
int a = 0, b = 0;
void DoSomething(ref int a, ref int b) {
a = 1;
b = 2;
}
Console.WriteLine(a); // Prints 1
Console.WriteLine(b); // Prints 2
It's not inline and I personally would consider a class or a struct before using the ref or the out keyword. Let's consider the theory: when you want to return multiple things, you have in fact an object that has multiple properties which you want to make available to the caller of your function.
Therefore it is much more correct to actually create an object (either by using a class or a struct) that represents what you want to make available and returning that.
The only time I use the ref or the out keyword is when using DLL imports because those functions often have pointers as their calling arguments and I personally don't see any benefit in using them in your typical normal application.
To do this inline, I think you would have to have another method that takes your struct and gives you the string you are looking for.
public string NewMethod(object yourStruct)
{
return string.Format("{0} {1}", yourStruct.value1, yourStruct.value2);
}
Then in the page, you do this:
Label1.Text = NewMethod(multipleReturnFunction(parameter));
C# doesn't have Inline functions, but it does support anonymous functions which can be closures.
With these techniques, you can say:
var firstString=default(String);
var secondString=default(String);
((Action<String>)(arg => {
firstString="abc"+arg;
secondString="xyz";
}))("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
((Action<String>)(arg => {
firstString="123"+arg;
secondString="456";
}))("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
or name the delegate and reuse it:
var firstString=default(String);
var secondString=default(String);
Action<String> m=
arg => {
firstString="abc"+arg;
secondString="xyz";
};
m("wtf");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
m("???");
label1.Text=firstString+secondString;
Debug.Print("{0}", label1.Text);
So, do you really need a method returns multiple values?
Each method can return only one value. Thats how methods defined in .NET
Methods are declared in a class or struct by specifying the access
level such as public or private, optional modifiers such as abstract
or sealed, the return value, the name of the method, and any method
parameters
If you need to return more than one value from method, then you have three options:
Return complex type which will hold all values. That cannot help you in this case, because you will need local variable to store value returned by method.
Use out parameters. Also not your case - you will need to declare parameters before method call.
Create another method, which does all work and returns single value.
Third option looks like
Label1.Text = AnotherMethod(parameters);
And implementation
public string AnotherMethod(parameters)
{
// use option 1 or 2 to get both values
// return combined string which uses both values and parameters
}
BTW One more option - do not return values at all - you can use method which sets several class fields.
For example if both values are int type it adds them.... ie 2+2=4
if both values are float....ie 2.2+2.3=4.5
or if one value is string and second is int...ie 1 + Pak=1Pak
We will get these two values from user using tfwo textboxes
This would be one way of doing it. Without having to convert to string and than back to numeric.
public object Add(IConvertible a, IConvertible b)
{
if(IsNumeric(a) && IsNumeric(b))
return a.ToDouble(CultureInfo.InvariantCulture) + b.ToDouble(CultureInfo.InvariantCulture);
return a.ToString() + b.ToString();
}
public static bool IsNumeric(object o)
{
var code = (int)Type.GetTypeCode(o.GetType());
return code >= 4 && code <= 15;
}
You can't do it using generics. You'll receive string from your textbox anyway. The only thing to do is to implement it "manually" exactly this way as you said:
public string TrySumTwoStrings(string input1, string input2)
{
double numeric1, numeric2;
if (Double.TryParse(input1, out numeric1) && Double.TryParse(input2, out numeric2))
return (numeric1 + numeric2).ToString();
return input1 + input2;
}
There's no way to use generics if we have no different types (everything is typed as string here).
You wouldn't, generics cannot be constrained in a way to support arithmetic operators (or concatenation). You would need to create overloads.
public int Add(int x, int y)
public double Add(double x, double y)
public decimal Add(decimal x, decimal y)
// etc.
Of course, you still have the problem of determining how exactly to parse your data. The source being a TextBox, the data will inherently be strings. You will have to determine which type of number it should be, if any.
If doing this for a real application, you shouldn't have this problem. Your textbox should be expected to receive input from the user in the form of an integer, or a decimal, or a string, etc. If it's not convertible to the proper type, it's an invalid input from your user. You wouldn't want the input to have to be magically deduced.
string Str1 = textBox1.Text.Trim();
string Str2 = textBox2.Text.Trim();
double Num1,num2;
bool isNum1 = double.TryParse(Str1, out Num1);
bool isNum2 = double.TryParse(Str2, out Num2);
if (isNum1 && isNum2)
MessageBox.Show((isNum1 + isNum2).ToString());
else
MessageBox.Show( Str1 + Str2);
Check out http://www.yoda.arachsys.com/csharp/miscutil/ The MiscUtil library. It contains some very clever Expression Tree stuff to allow operators with generics. It's not going to work exactly how you want (as others have stated, you can't constrain types to have operators) but it should do exactly what you want.
I don't know how it handles adding different types together though, I've not tried that.
I would think it would take some processing the values before hand in order with things like String.PArse, Int.Parse, etc...
Take them in order of compplexity first because 1 will convert to string, however x will not convert to integer or float.
Officially changed my answer to same as comment...
Best suggestion I have on that would be allow the user to select what type to interpret the data as and pass to the appropriate function based on what the user meant, there would be too many ways to interprets char strings to know what the users intention was, code processes logic not intent.
I'm familiar with the System.Numerics.BigInteger class, but in my app, I'm only ever dealing with positive integers. Negative integers are an error case, and it'd be nice if there was an unsigned equivalent of the BigInteger type so I could remove all of these checks. Does one exist?
There's nothing in the framework, no. I would try to centralize the checks in as small a public API as possible, and then treat the data as valid for the rest of the time - just as you would for something like null checking. Of course, you still need to be careful if you perform any operations which could create a negative value (e.g. subtracting one from another).
You may be able to make the code slightly neater by creating an extension method, e.g.
public static void ThrowIfNegative(this BigInteger value, string name)
{
if (value.Sign < 0)
{
throw new ArgumentOutOfRangeException(name);
}
}
... and use it like this:
input.ThrowIfNegative("input");
You could potentially create your own UBigInteger struct which contained a BigInteger, and perform operations between different values by using the BigInteger implementation and checks, but I suspect that would be quite a lot of work for relatively little benefit, and may have performance implications if you're using it for a lot of calculations.
Well, let's have a look at a simple example
uint a=1;
uint b=2;
uint c=a-b;
Console.WriteLine(c);
gives you the output 4294967295 (=2^32-1).
But what if you had an unsigned BigInteger with similar behaviour?
UBigInteger a(1);
UBigInteger b(2);
UBigInteger c=a-b;
Console.WriteLine(c.ToString());
What should that be? Of course, from what you wrote one can assume you might expect to get some kind of exception in this case, but such behaviour would not be consistent to int. Better introduce the checks for < 0 where you need them, for example, like the way Jon Skeet suggested.
If you only use a reasonably small subset of the the BigInteger API, writing your own wrapper class is easy if laborious. Here is some sample code to demonstrate that it needn't be that big an operation:
public struct UnsignedBigInteger
{
private BigInteger value;
private UnsignedBigInteger(BigInteger n) { value = n; }
public UnsignedBigInteger(uint n) { value = new BigInteger(n); }
// ... other constructors ...
public static UnsignedBigInteger operator+(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
{
return new UnsignedBigInteger(lhs.value + rhs.value);
}
public static UnsignedBigInteger operator-(UnsignedBigInteger lhs, UnsignedBigInteger rhs)
{
var result = lhs.value - rhs.value;
if (result < BigInteger.Zero) throw new InvalidOperationException("value out of range");
return new UnsignedBigInteger(result);
}
// ... other operators ...
}
If negative values present such a problem, is possible to eliminate them somehow so that bad data(the negative values) doesn't even reach your logic ? This will eliminate the check all together. Could you post a short snippet of what you are doing ?
There isn't any support in the framework to declare BigInteger as unsigned. However, you could create a static method to check if the number is negative or not.
public static void ValidateBigIntForUnsigned(BigInteger bigInteger)
{
if(bigInteger.Sign < 0)
throw new Exception("Only unsigned numbers are allowed!");
}
I was trying to do something like this -
List<short> listofshorts= new List<short>();
int s = listofshorts.Sum();
//this does not work...but same code works for a list of ints..
I got this compilation error -
'System.Collections.Generic.List' does not contain a definition for 'Sum' and the best extension method overload 'System.Linq.Queryable.Sum(System.Linq.IQueryable)' has some invalid arguments
Can anyone suggest how can I use an extension method to calculate the sum of shorts? For some reason the extension method does not support it ...
int s = listofshorts.Sum(d => d);
You can provide the lambda for the method:
List<short> listofshorts= new List<short>();
int s = listofshorts.Sum(a => (int)a);
// This throws an InvalidCastException in .NET 3.5 SP1+
// DO NOT USE THIS CODE
listOfShorts.Cast<int>().Sum();
In the interest of posterity, and pointing out this seemingly obvious solution doesn't work - I'm going to leave this answer with the following links about .NET 3.5 SP1+ behavior:
Puzzling Enumerable.Cast InvalidCastException
http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/08/10/net-fx-3-5-sp1-two-perf-improvements-linq-to-objects-and-linq-to-sql.aspx
http://blogs.msdn.com/b/ed_maurer/archive/2008/02/16/breaking-change-in-linq-queries-using-explicitly-typed-range-variables.aspx
You could do
int s = listofshorts.Aggregate((i1,i2) => i1+i2);
Like the others have suggested, you will need to cast the short objects to a type which is supported by the Enumerable.Sum method. Unfortunately there are no overloaded Sum method for some of the types like ulong, etc.
If you're gonna be needing it very often though, I'd recommend writing an extension method yourself, here's one I did a while back for ulong and ulong?, you can do something very similar for short or any other types you need:
public static ulong Sum(this IEnumerable<ulong> source)
{
var sum = 0UL;
foreach (var number in source)
{
sum += number;
}
return sum;
}
public static ulong? Sum(this IEnumerable<ulong?> source)
{
var sum = 0UL;
foreach (var nullable in source)
{
if (nullable.HasValue)
{
sum += nullable.GetValueOrDefault();
}
}
return sum;
}
P.S. my implementations are based on the Enumerable.Sum implementation after I took a peek with reflector purely out of curiosity :-P
I would probably chose the .ForEach() extension, you don't need any casting here
short sum = 0;
myListOfShort.ForEach(val => sum += val)