How do I get the property name of an object array to use in a SWITCH / CASE function as follows? Any other suggestions on how to do this are appreciated.
Object[] objEURUSD = ConvertStringtoObjectArray(string val1);
Object[] objAUDUSD = ConvertStringtoObjectArray(string val2);
Object[] objGBPUSD = ConvertStringtoObjectArray(string val3);
Example Function Use
Object[] mvavgEURUSD = mvavgObject(objEURUSD);
private Object[] mvavgObject(Object[] val)
{
string sym = val.ToString() // this does not return the name it returns 'System.Object'
switch (sym)
{
case "objEURUSD":
// do something
break;
case "objAUDUSD":
// do something
break;
case "objGBPUSD":
// do something
break;
}
}
I could include the name of the object 'EURUSD' in the Object Array itself, but it's already inlcuded in the name of the object.. I just can't figure out how to reference the name of the object.. either I don't know or I am not conversant with Reflection.
I appreciate your help or suggestions on the matter.
How do I get the property name of an object array to use in a SWITCH / CASE function ?
By not doing the conversion. You can use a string in a switch statement, but not an object[].
You can't because there is no such "name" for an object. That wouldn't even make sense - many variables can hold a reference to the same object. Which one should be the "name"?
Imagine for a moment that there would be such a function called GetName(). What would the program output in each of these cases?
Case 1:
var a = new MyObject();
var b = a;
Console.WriteLine(GetName(b)); // Is it "a" or "b"?
Case 2:
Console.WriteLine(GetName(new MyObject())); // What is the name now?
Case 3:
Console.WriteLine(GetName(null)); // I guess you can return null here, but see case 4:
Case 4:
MyObject a = null;
Console.WriteLine(GetName(a)); // Should this be "a" or null?
And so on and so forth.
If you want to give your objects "names", you'll have to do so yourself. Perhaps create a "NamedObject" wrapper class like this:
class NamedObject<T>
{
public readonly T Object;
public readonly string Name;
public NamedObject(string name, string value)
{
this.Object = value;
this.Name = name;
}
}
Without further information, I can only guess what ConvertStringtoObjectArray does. My guess is that it looks something up using the string as a key, and then returns an array of some values.
In most cases, I would expect that the original string is no longer contained in the object array. Therefore, obviously, you cannot retrieve it, so you will have to “remember” it, i.e. pass it around.
For example, instead of
Object[] objEURUSD = ConvertStringtoObjectArray(myVal);
Object[] mvavgEURUSD = mvavgObject(objEURUSD);
private Object[] mvavgObject(Object[] val)
{
// ...
you could write something like this:
Object[] mvavgEURUSD = mvavgObject(myVal);
private Object[] mvavgObject(string val)
{
Object[] objEURUSD = ConvertStringtoObjectArray(val);
// The string is in the parameter ‘val’, so we can use it here
switch (val)
{
// ...
}
}
the default behavior of ToString() is to return the class name. This can be overridden in any class as all classes inherit from object. string.ToString() is the behavior you are looking for so you probably need to first cast the object back to string (the array part is tricky though since I don't know what the ConvertStringtoObjectArray method does), but you need to do a cast to access what you are looking for.
I assume that the object[] is a char[]? if so the cast should be as easy as casting the object to a char[] and then to the string.
if the variable declaration of "objEURUSD" is in your current scope, you could compare your parameter to that variable to see if both are referencing the same object ... this won't lookup some sort of name, but maybe it's what you want...
Object[] objEURUSD; //initialized somewhere else
private Object[] mvavgObject(Object[] val)
{
if(val==objEURUSD)
{
//it's the array referenced by objEURUSD ...
}
}
as an alternative, you could use a Dictionary<string,Object[]> or Dictionary<Object[],string> to store your arrays, so you can lookup the array for a given name or vice versa
Related
I am writing an interop between a php service and our crm. One of the things I need to do is make sure that simple types get converted ToString() for use later in a json converter.
I am not sure even what the name is for 'simple types' but it can be defined like this... "an object that represents a low level variable type, containing a single value, not a class or anything with executable functions etc"
I've found that int, string, bool, double, and surprisingly enum will ToString() with pretty predictable results.
int x = 0;
bool y = true;
double z = 1.59 // money
CustomEnum theEnum = CustomEnum.somevalue;
x.ToString() results in "0"
y.ToString() results in "true"
z.ToString() results in "1.59"
theEnum.ToString() results in "somevalue"
But if I use this:
List<int> iList = new List<int>();
iList.Add(1);
MyClass theClass = new MyClass();
iList.ToString() results in "System.Collections.Generic.List`1[System.Int32]"
theClass.ToString() results in "STTI.NKI.Interop.MyClass"
I'm not limited to lists. I could have an ExpandoObject, or a class etc.
I understand EXACTLY why this happens, and I want to know if there is a quick way to determine if an object of unknown type will ToString() into an expected value, and not the type name. I find it an antipattern to do something like
switch (theObject.GetType())
case typeof(int):
case typeof(bool):
case typeof(doulble):
etc
I am not sure what the terms are, so googling my answer is proving difficult.
So you want to check whether a type has a overridden ToString method? Why not just check whether the value returned by ToString is equal to the value returned by the default implementation of ToString?
From here, we know the default implementation of ToString is
return GetType().ToString();
So, we can use this to check whether an object has overridden the ToString method:
bool toStringOverridden = someObject.GetType().ToString() !=
someObject.ToString();
The ToString method is a virtual one and the default implementation is defined in the Object class and simply returns the name of the type of the object:
public virtual string ToString()
{
return this.GetType().ToString();
}
int for example, overrides this method to return a meaningful representation.
What you can do is use reflection to detect whether a type overrides the ToString method like this:
public static bool OverridesToString(Type type)
{
return type.GetMethod("ToString", new Type[0]).DeclaringType != typeof(object);
}
If it does, there is a very good chance that the ToString method would return something meaningful.
Option 1: make sure that every Object will overwrite ToString().
Option 2: Use reflection to get all object properties and concat them.
Maybe you can do something similar to this:
bool ToStringIsTyped<T>(T myObj)
{
return myObj.ToString().Contains(typeof(T).FullName);
}
It may not work in all cases, but possibly could be expanded
I Think this is what you are looking, in the GetMethod the second argument is an empty array to watch for the .ToString(), just convert the i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object) to a function and there you go.
class Program
{
static void Main(string[] args)
{
int i = 55;
var s = "some string";
var x = new List<string>();
Console.WriteLine(i.ToString());
Console.WriteLine(i.GetType().GetMethod("ToString", new Type[] { }).DeclaringType == typeof(object));
Console.WriteLine(s.ToString());
Console.WriteLine(s.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
Console.WriteLine(x.ToString());
Console.WriteLine(x.GetType().GetMethod("ToString",new Type[]{}).DeclaringType == typeof(object));
}
}
...way to determine if an object of unknown type will ToString() into an expected value, and not the type name...
The default implementation of ToString() on object, according to documentation, returns "the fully qualified name of the object's type".
So we could come up with the hypothesis that whenever ToString() is overridden, its output will be "useful" in the sense you specified in the question.
To detect whether a function called is an override, we can make use of this answer, like so:
if(typeof(ObjectX).GetMethod("ToString").DeclaringType == typeof(ObjectX))
{
/* ObjectX has overridden ToString() */
}
else
{
/* ObjectX has inherited ToString() from its base class(es) */
}
Using reflection can add too much overhead, so I reckon it's better to create a generic method and add a constraint like: where T : IFormattable
I want to create a method that takes a dynamic input parameter and returns a dynamic that I can use to fill a typed variable. Is there a way to get the type of the variable being assigned to from within the method?
double dbl = AssignValue("Hello");
public dynamic AssignValue(dynamic ValueToAssign)
{
Type type = //do something to get the type of variable "dbl"
switch (type.Name)
{
case "Double":
return double.Parse(AssignValue);
break;
case "Decimal":
return decimal.Parse(AssignValue);
break;
//...
}
}
I tried to locate something in the StackFrame but, with no luck.
Any terminology to research further would be very much appreciated as well.
Is there a way to get the type of the variable being assigned to from within the method?
No. There is no way for a method to retrieve any information about the variable that its result will be assigned to.
However, you could use generics to tell the method the type of object you want it to return:
double dbl = AssignValue<double>("Hello");
public T AssignValue<T>(object valueToAssign)
{
Type type = typeof(T);
switch(type.Name)
{
//...
}
}
Is there any way to make an out parameter of a method optional? I have a method that needs several parameters to return null most of the time, but sometimes they will have a value. I am trying to find out if there is a better way to accomplish this than by setting the values to null first, or setting them to null after the if/else. This may be the only way to do it, but it would be nice if there were optional out parameters or something equivalent. Here is the code:
private static void GetInitInfo(string initLine, string ncPointType, out double? relinquishDefault, out bool? ignoreRelinquishDefault, out bool? closedForStart, out bool? adjustDisabled)
{
relinquishDefault = null;
ignoreRelinquishDefault = null;
closedForStart = null;
adjustDisabled = null;
switch (ncPointType)
{
case "MSD":
adjustDisabled = LastToken<bool?>(initLine);
break;
case "BO":
relinquishDefault = SecondToken<double>(initLine);
closedForStart = ThirdToken<bool?>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "MSO":
closedForStart = SecondToken<bool?>(initLine);
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = !ForthToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
case "AD":
relinquishDefault = ThirdToken<double>(initLine);
ignoreRelinquishDefault = false;
break;
case "BD":
relinquishDefault = SecondToken<double>(initLine);
adjustDisabled = LastToken<bool?>(initLine);
ignoreRelinquishDefault = false;
break;
case "AOS":
relinquishDefault = FirstToken<double>(initLine);
ignoreRelinquishDefault = !ThirdToken<bool?>(initLine);//ignoreRelDef would be reverse of use initial value
break;
}
}
This isn't not allowed according to the C# 4.0 Spec: section 21.1.
A workaround is to overload with another method that does not have out or ref parameters.
I believe this question is asking about having to assign values inside the method with out parameters, and whether there is any way to circumvent that, i.e. by leaving the values unassigned rather than explicitly having to assign them null.
e.g. Do you have to write:
public bool OutMethod(out int? output)
{
output = null;
return true;
}
Or is there a way to do something like:
public bool OutMethod(out int? output)
{
return true;
}
With the same result?
Short answer is no, this can't be avoided. See the documentation for an example which includes assigning null explicitly, and states:
Note that the third argument is assigned to null. This allows methods to return values optionally.
Examples of this can also be found in the .NET framework. e.g. Dictionary<TKey,TValue>'s TryGetValue method:
public bool TryGetValue(TKey key, out TValue value)
{
int num = this.FindEntry(key);
if (num >= 0)
{
value = this.entries[num].value;
return true;
}
value = default(TValue);
return false;
}
Note the explicit assignment to default(TValue)
Use the overload with signature that does not have out parameters:
private static void GetInitInfo(string initLine, string ncPointType)
{
double? relinquishDefault;
bool? ignoreRelinquishDefault;
bool? closedForStart;
bool? adjustDisabled;
GetInitInfo( initLine, ncPointType, out relinquishDefault, out ignoreRelinquishDefault,
out closedForStart, out adjustDisabled);
}
The explanation is quite simple: You can do it. Just assign an out parameter inside the method to the desired value.
Now you can ask yourself, why can't we do that in the method signature? Well, let us have a look at the normal optional value parameters. They are assigned a predefined value if they are not assigned by the caller. So caller knows the value, which will be passed if the parameter is not set explicitly. It has a control of it and it is responsible for that decision.
Since the caller of the method is NOT responsible for the assignment of the out parameter, it makes no sense to offer a default value. The only thing you could achieve, by having a default out parameter value is to let the caller know what one of the possible values of that out parameter would be. But would that make sense? When will this value be used? Under what condition? All this is still hidden from the caller. So there is no real benefit from having an optional out parameter value, apart from having a possiblity to set it inside the signature instead of the method body.
So, having that said, the following would not make much sense:
public bool TrySomething(out string outObject = "default value") { ... }
However, what would be cool is to allow the following method
public bool TrySomething(out string outObject) { ... }
to be invoked as follows:
bool result = TrySomething();
And have that behind the scenes equivalent to:
string dummyWhichWillNeverBeUsed;
bool succeeded = TrySomething(out dummyWhichWillNeverBeUsed);
Unfortunately, that is not allowed.
And of course, as explained in other answers, you can always have overloads without out parameter.
When I declare a method with parameters, and inside my method I assign value to those parameters, those parameters turn into variables?
My question is, can I Say: "The parameter of my method is also a variable when I use it inside my method"?
Example:
public int returnDays(int month)
{
month = getMonth();
//"Can I say : month is a variable?"
}
//"Can I say : month is a variable?"
yes it is a local variable to that method.
Official docs on passing arguments
Yes it is called variable and you can call it variable and you can use it. Variable is a named place holder in memory whoes value could be changed in program
In computer programming, a variable is a storage location and an
associated symbolic name (an identifier) which contains some known or
unknown quantity or information, a value. The variable name is the
usual way to reference the stored value; this separation of name and
content allows the name to be used independently of the exact
information it represents. The identifier in computer source code can
be bound to a value during run time, and the value of the variable may
thus change during the course of program execution, reference.
You have 2 questions
I declare a method with parameters, and inside my method I assign
value to those parameters, those parameters turn into variables
Short Answer YES they are variables
can I call variables to the parameters of the method when I use them
inside my method
As far as your context is concerned Yes you can use them but in a broader perspective what variables are accessible to you inside the method scope you should read this before going in to development details
I don't entirely get your question. Yes, "month" is a variable. However, I'm unsure on what you're trying to achieve by assigning it.
The int type derives from struct, and this means that it isn't passed by reference. When you call returnDays(x), x itself isn't passed and a copy of it is made.
If you, instead, wanted to change its value AND return the days, you'd need to use the ref or out keywords. The former basically passes a pointer to x, which can be used as your function pleases. The latter, however, is stricter and requires the function to initialize whatever value is passed through it.
So, this is the code you'd end up with
public int ReturnDays(out int month)
{
month = GetCurrentMonth();
return GetDays(month);
}
But still, I am not sure if this is the kind of answer you wanted.
First of all, is this C# or Java? Each language has its own eccentricities.
If C# use the out statement that KappaG3 showed.
If Java,
just use a return statement inside your function/method:
return getMonth();
If you need to return multiple values, you can pass objects and then assign to those objects inside the function/method. Objects are passed by reference where as primitives are passed by value. integer is an Object but doesn't act like one as you can see from:
//
public class Main {
public static void main(String[] args) {
int value1 = 0;
Integer value2 = new Integer(0);
MyObject value3 = (new Main()).new MyObject(0);
passByVal(value1);
passByRef(value2);
passByRef(value3);
System.out.println("value1 = " + value1);
System.out.println("value2 = " + value2);
System.out.println("value3 = " + value3);
}
class MyObject
{
public int value = 0;
public MyObject(int value) { this.value = value; }
#Override
public String toString() {
return value + "";
}
}
public static void passByVal(int i)
{
i = 7;
}
public static void passByRef(Integer i)
{
i = new Integer(7);
}
public static void passByRef(MyObject o)
{
o.value = 7;
}
}
which return the output:
0
0
7
so if you need to return a bunch of values I recommend passing objects or returning an object that is specially designed to hold all those values
I am trying to make an API, one function in that API takes Enum as parameter which then corresponds to a string which is used.
public enum PackageUnitOfMeasurement
{
LBS,
KGS,
};
The trivial method to code this will have to list every case in code. But as their are 30 cases so I am trying to avoid that and use Dictionary Data Structure, but I can't seem to connect the dots on how will I relate value to enum.
if(unit == PackageUnitOfMeasurement.LBS)
uom.Code = "02"; //Please note this value has to be string
else if (unit == PackageUnitOfMeasurement.KGS)
uom.Code = "03";
Here is one way you could store the mapping in a dictionary and retrieve values later:
var myDict = new Dictionary<PackageUnitOfMeasurement,string>();
myDict.Add(PackageUnitOfMeasurement.LBS, "02");
...
string code = myDict[PackageUnitOfMeasurement.LBS];
Another option is to use something like the DecriptionAttribute to decorate each enumeration item and use reflection to read these out, as described in Getting attributes of Enum's value:
public enum PackageUnitOfMeasurement
{
[Description("02")]
LBS,
[Description("03")]
KGS,
};
var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
false);
var description = ((DescriptionAttribute)attributes[0]).Description;
The benefit of the second approach is that you keep the mapping close to the enum and if either changes, you don't need to hunt for any other place you need to update.
You can specify the number value of the enum elements
public enum PackageUnitOfMeasurement {
None = 0,
LBS = 2,
KGS = 3,
TONS = 0x2a
};
Then you can simply convert the units with
uom.Code = ((int)unit).ToString("X2");
NOTE:
The fundamental question is, whether it is a good idea to hard-code the units. Usually this sort of things should be put into a lookup table in a DB, making it easy to add new units at any time without having to change the program code.
UPDATE:
I added an example containing a HEX code. The format "X2" yields a two digit hex value. Enter all numbers greater than 9 in hex notation like 0xA == 10, 0x10 == 16 in c#.
I would use attributes attached to the enum. Like this:
var type = typeof(PackageUnitOfMeasurement);
var memInfo = type.GetMember(PackageUnitOfMeasurement.LBS.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
false);
var description = ((DescriptionAttribute)attributes[0]).Description;
This is taken from this question, Getting attributes of Enum's value. Which asks specifically about returning Enum attributes.
Oded's solution is fine, but an alternative that I've used in the past is to use attributes attached to the enum values that contain the corresponding string.
Here's what I did.
public class DisplayStringAttribute : Attribute
{
private readonly string value;
public string Value
{
get { return value; }
}
public DisplayStringAttribute(string val)
{
value = val;
}
}
Then I could define my enum like this:
public enum MyState
{
[DisplayString("Ready")]
Ready,
[DisplayString("Not Ready")]
NotReady,
[DisplayString("Error")]
Error
};
And, for my purposes, I created a converter so I could bind to the enum:
public class EnumDisplayNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Type t = value.GetType();
if (t.IsEnum)
{
FieldInfo fi = t.GetField(value.ToString());
DisplayStringAttribute[] attrbs = (DisplayStringAttribute[])fi.GetCustomAttributes(typeof(DisplayStringAttribute),
false);
return ((attrbs.Length > 0) && (!String.IsNullOrEmpty(attrbs[0].Value))) ? attrbs[0].Value : value.ToString();
}
else
{
throw new NotImplementedException("Converter is for enum types only");
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Oded's solution probably performs faster, but this solution has a lot of flexibility. You could add a whole bunch of attributes if you really wanted to. However, if you did that, you'd probably be better off creating a class rather than using an enum!
The default value of PackageUnitOfMeasurement.LBS is 0 likewise PackageUnitOfMeasurement.KBS is 1.
So a collection of PackageUnitOfMeasurement is really a collection that contain integer values ( i.e. int ).
Your question is not entirely clear....
A Dictionary collection has a Key and a Value it sounds like you want use PackageUnitOfMeasurement has a Key which is trivial as casting the value to an integer.
PackageUnitOfMeasurement example = PackageUnitOfMeasurement.LBS
int result = (int)example;
var myDict = new Dictionary<PackageUnitOfMeasurement,string>();
myDict.Add(result,"some value here"