So i have this old code that uses Firebird, i took the code from there since it worked perfectly, but here it doesnt. and throws me a InvalidCastException.
So wat am i trying
animal.FeedScheduleType = (BcFeedScheduleType)drAnimal["feedschedule_type"];
So i try to pull something out my datatable and place it in animal.FeedScheduleType. Now my cast points a a public enum
public enum BcFeedScheduleType
{
Default = 0,
FromList = 1,
Group = 2
}
and animal.FeedScheduleType is
private BcFeedScheduleType _feedScheduleType;
public BcFeedScheduleType FeedScheduleType
{
get { return _feedScheduleType; }
set { _feedScheduleType = value; }
}
But whenever it hits this it throws me the InvalidCastException error and i dont know why, i searched here and google but was unable to find anything about casts like this.
Edit: the Type inside the database is a integer
Try this:
animal.FeedScheduleType = (BcFeedScheduleType)Convert.ToInt32(drAnimal["feedschedule_type"]);
Here is a fiddle.
Have you tried casting to an int first?
animal.FeedScheduleType = (BcFeedScheduleType)(int)drAnimal["feedschedule_type"];
My guess is that your drAnimal is returning a string and not an int. If this is the case, then
animal.FeedScheduleType = (BcFeedScheduleType)Int.Parse(drAnimal["feedschedule_type"]);
If you are not sure what type drAnimal is, you can do something like:
var feedschedule_type = drAnimal["feedschedule_type"];
Console.WriteLine("feedschedule_type is {0}", typeof(feedschedule_type));
Basically, you need to get it into an int and then use the standard cast as you've done in your question.
Finally, make sure the feed schedule type has a valid value. I.e., make sure its value is either 0, 1 or 2.
I actually just ran into this recently when using SqlParameter.
My guess is that drAnimal["feedschedule_type"] is being stored as a SqlDbType.Int or object. In order to cast my parameter, I had to do something similar to the following:
(int)(SqlDbType.Int)(drAnimal["feedschedule_type"]);
You may have to use a similar chain to get the actual int value and coerce it into your Enum.
Related
I am developing my first registration form in ASP.NET MVC and I am presenting the following error
Argument 2: cannot convert from 'out string' to 'out int'
var ticketPriorityInput = "ALTO";
if (int.TryParse(Request.Form["ticketPriorityInput"], out ticketPriorityInput) == false)
{
}
ticketPriorityInput is of type string
I do this because I need to validate that when the ticketPriorityInput field is saved to save it by default with the string "ALTO", you can tell me how it is the best way to do it or how I can fix it
I explain better a form but depending on the session variables certain fields are loaded, ticketPriorityInput has to go in both one and the other, the difference is that in which I need also goes ticketPriorityInput but it is not being entered I need it to be stored by default value "ALTO"
var ticketPriorityInput is explicity a string because you initialized it to a string.
try:
var ticketPriorityInput = 0;
if (int.TryParse(Request.Form["ticketPriorityInput"], out ticketPriorityInput) == false)
{
}
if you dont want to change ticketPriorityInput, create a different variable that is an int for ticketPriorityInput to save to.
If I understand you correctly, you want to convert the value of Request.Form["ticketPriorityInput"] to int and save the result in ticketPriorityInput if successful, and if not successful, you want ticketPriorityInput to contain the string "ALTO".
So you would still have to use two variables; there's no way getting around the requirement to pass an int to the int.TryParse() method. But you can make ticketPriorityInput into type dynamic and use this:
dynamic ticketPriorityInput = "ALTO";
if (int.TryParse(Request.Form["ticketPriorityInput"], out int tInt))
{
ticketPriorityInput = tInt;
}
Now, if the conversion is successful ticketPriorityInput will contain the converted integer, otherwise the value "ALTO".
After reading the comments of all users and none understood what my question was saying despite being updated with a clearer explanation I found the solution to my problem in this way
var ticketPriorityInput = Request.Form["ticketPriorityInput"];
var ticketPriorityInputByDefault = "ALTO";
if (String.IsNullOrEmpty(ticketPriorityInput)){
ticketPriorityInput = ticketPriorityInputByDefault;
}
im a bit stuck right now and i hope u can quickstart me.
i Want a Method that i can for Example call like this:
string myString = GetSomething(typeof(string));
OR
DateTime dt = GetSomething(typeof(DateTime));
while GetSomething always returns the Type i give in as Argument.
Is it possible to make this kind of signature? Or do i blow my head up for nothing right now?
Im atm stuck with this approach:
public T GetSomething<T>(Type t ) where T : struct
Assuming I've read your question correctly, all you should need is:
public T GetSomething<T> {
return default(T);
}
DateTime dt = GetSomething<DateTime>();
I have a tricky question that has been befuddling me for a while. I have the following code declaration...
namespace ESEGURCI.WEB.BusinessLogicLayer.Commons
{
public static class ParameterUtilities
{
public enum ParameterEnum
{
MAX_LOGIN_ATTEMPTS,
AUDIT_MODIFICATIONS
}
}
}
and I call the code like so "ParameterUtilities.ParameterEnum.MAX_LOGIN_ATTEMPTS" Problem is once every full moon I get the error "object reference not set to an instance of an object" on this line... It's like the code only works 99.9% of the time...
The only thing that occurs to me is that since the enum is a value type that there can be a chance that the enum is null when the static class is called... But I can't find any documentation on this behavior...
Can someone enlighten me why this happens? I know I should probably remove the enum out of the static class, and declare the enum as standalone but I'd like to know why this is happening first...
Thanks,
S
Update
Ok, to everyone who asked for more code, the following is the full function where the error occurs...
public static int GetPageSize(int companyId)
{
int pageSize = 0;
// error happens bellow this line
ESEGURCI.WEB.BusinessLogicLayer.Entities.Parameter parameter = ESEGURCI.WEB.BusinessLogicLayer.Entities.Parameter.GetParameter(ParameterUtilities.ParameterEnum.AUDIT_MODIFICATIONS.ToString(), companyId);
// error happens above this line
int.TryParse(parameter.Value, out pageSize);
return pageSize;
}
ParameterUtilities.ParameterEnum.MAX_LOGIN_ATTEMPTS won't ever throw a null reference exception, no matter what the Moon looks like. The error is probably triggered by an other instruction on the same line (assignment to a variable?).
An enum can't be null.
Split up the line as in the listing below and see which statement throws the exception. I bet it happens somewhere in Parameter.GetParameter():
using ESEGURCI.WEB.BusinessLogicLayer.Entities;
// ...
var auditModifications =
ParameterUtilities.ParameterEnum.AUDIT_MODIFICATIONS.ToString();
var parameter = Parameter.GetParameter(auditModifications, companyId);
Enum (and any other type) cannot have null value, because it isn't a value it is a type.
The exception is thrown by something else.
As already stated your enum will not be where the error is coming from. Based on your update, I would say the NRE is most likely coming from your GetParameter method.
Okay, for whatever reason I can't seem to figure this little problem out.
I have the following enum:
public enum EFeedType
{
TypeOne = 1,
TypeTwo = 2
}
Now, I am going to be getting the numeric value from a database. Well, I need to cast the int value from the DB to the enum type:
EDIT:
The database type is integer, so I do not need to cast from string.
END EDIT
EFeedType feedType = (EFeedType) feedId;
However, when I do this, and pass in value of 2 I get the following error:
Instance validation error: '2' is not a valid value for [Namespace Goes Here].EFeedType.
Any thoughts on what I might be doing wrong or missing?
EDIT
Here is the code I am using:
//GetFeed will return an int value which is pulled from the database
int feedId = new FeedEngine().GetFeed("FeedName");
//Convert the ID to the Enum
EFeedType feedType = (EFeedType) feedId;
//Set the User Control FeedType Enum to the enum
FeedControl.FeedType = feedType;
//Show the user control
FeedControl.Visible = true;
EDIT - More Info
Okay, after seeing JSkeet's response, I see that If my feedId = 1 then it will set the enum value to TypeTwo instead of TypeOne like it should. Maybe I need a Default = 0 value in my enum for this to work? But there has to be a better way, because what if my values are not in sequence.
Your error won't be coming from the line you showed it on. I strongly suspect it's coming from this line:
FeedControl.FeedType = feedType;
My guess is that that property is doing some validation - and that it doesn't know about the relevant value.
EDIT: Note that if you do want to find out if a value is valid, use Enum.IsDefined. Enum.Parse will not throw an exception for an incorrect numeric value, so long as it's in the right range.
Have you really posted the exact code of the enum? Because if it doesn't explicitly specify the "= 1" and "= 2" it will autoincrement from 0, and that will be your problem.
If you could demonstrate all of this with a short but complete program it would really help. There's no need to go to the database, and no need to do anything with a user control.
I just tried the following and it worked perfectly. You might want to break your code out into a little test project to see what's going on.
// enum definition
public enum EFeedType {
TypeOne = 1,
TypeTwo = 2,
}
// usage
private void TestEnum() {
Int32 feedId = 2;
EFeedType stuff = (EFeedType)Enum.Parse(typeof(EFeedType), feedId.ToString());
Response.Write(stuff.ToString());
}
I have a scenario where I'm using a Dictionary to hold a list of transaction types that a certain system accepts. The key in the Dictionary is an enum field, the value is an int.
At some point in the system, we're going to want to do something like this:
sqlCommand.Parameters.AddWithValue("#param", LookupDictionary[argument.enumField]);
When we look up the field in the dictionary, we're going to get the correct integer value to feed to the database. I've thought about actually using the enum int value for this, but that's not exactly right. We're interacting with a system where we need to feed a magic number in to represent the kind of update we're doing.
The code above works just fine. I have an initializer method that adds the known types:
LookupDictionary = new Dictionary<mynamespace.myproject.myclass.enumType, int>();
LookupDictionary.Add(enumType.entry1, 4);
LookupDictionary.Add(enumType.entry2, 5);
LookupDictionary.Add(enumType.entry3, 6);
This code also works fine.
But up above, before I actually get in to using the LookupDictionary, I validate that the request being made is actually set to an enum value we support. That's LookupDictionary's main reason to be, it holds the valid ones (there are valid enum entries that this method doesn't work with).
This is the code that doesn't work: the system fails to recognize that the enums match. In the debugger, I can see that the entries list in LookupDictionary does show that it has the value for entry2 - it just calls it like that, entry2. The incoming enumField on the other hand has the full namespace; mynamespace.myproject.myclass.enumType.entry2 - I imagine this is why it doesn't see them as being the same.
if (!LookupDictionary.ContainsKey(argument.enumField))
{
throw new InvalidOperationException("argument.enumField not valid in blahMethod.");
}
Did I mention that this is being passed across a WCF service? But I'm not using an auto-generated proxy ... both projects on both sides of the wire share the types as a project reference, and I build up my channel client in code.
Any ideas? Am I doing it wrong? Do Dictionaries with Enums as keys not work well? Is it a WCF thing?
Note: thanks for the suggestions regarding setting the enums up to contain the magic int. I wanted to set those in a configuration, however, as its possible that the "magic numbers" 4 5 and 6 might change down the road. So if I code them in to the enum as suggested:
public enum MyEnum
{
MyValue1 = 4,
MyValue2 = 5,
MyValue3 = 6
}
I lose the ability to write a method that sets up the magic numbers in the future at run time; instead it would require a code change.
Instead of using the enum as the key, use the integer representation of the enum.
For instance:
LookupDictionary = new Dictionary<int, int>();
LookupDictionary.Add((int)enumType.entry1, 4);
LookupDictionary.Add((int)enumType.entry2, 5);
LookupDictionary.Add((int)enumType.entry3, 6);
That way, you can use the same 'ContainsKey' method of the dictionary. I'm not sure this is much better performance than a List<int>
You shouldn't need a lookup table here at all:
public enum MyEnum
{
MyValue1 = 4,
MyValue2 = 5,
MyValue3 = 6
}
// Sample usage
MyEnum firstEnum = MyEnum.MyValue1;
int intVal = (int)firstEnum; // results in 4
// Enum Validation
bool valid = Enum.IsDefined(typeof(MyEnum), intVal); // results in true
Can you considered typing your enumeration explicitly as int (or whatever the underlying type is) and then setting the value of each of your enumerations to the database value? You've already tightly coupled the enumeration to the database, so either the relationship will be dictated in C# (current hard-coding) or by SQL (perhaps a proc that returns the ID as well as a string that can be parsed into an enumeration.)
Using the assumption that your enumeration is an int...
enum enumType {
entry1 = 4,
entry2 = 5,
entry3 = 6
}
When adding your parameter you would then just cast as the enum's underlying type.
sqlCommand.Parameters.AddWithValue("#param", (int)argument.enumField);
You can explicitly set the values of the enum using the syntax
enum ArgumentTypes {
Arg1 = 1;
Arg2 = 3;
Arg3 = 5;
}
You don't need to keep each value sequential in the enum for this syntax to work.
To validate that only parameters that are valid for the method are ever used, try this sample code. Note I suggest using an ArgumentException over an InvalidOperationException in this context.
public void DoDbWork(ArgumentTypes argType, object otherParameter)
{
if (argType == ArgumentTypes.Arg3) {
throw new ArgumentException("Argument of value " + argType + " is not valid in this context", "argType");
}
// Handle db transaction here
}
To add the int value as the parameter:
cmd.Parameters.AddWithValue("#paramName", (int)argType);