This Code:
Something = new Guid()
is returning:
00000000-0000-0000-0000-000000000000
all the time and I can't tell why? So, why?
You should use Guid.NewGuid()
Just a quick explanation for why you need to call NewGuid as opposed to using the default constructor... In .NET all structures (value types like int, decimal, Guid, DateTime, etc) must have a default parameterless constructor that initializes all of the fields to their default value. In the case of Guid, the bytes that make up the Guid are all zero. Rather than making a special case for Guid or making it a class, they use the NewGuid method to generate a new "random" Guid.
It's in System.Guid.
To dynamically create a GUID in code:
Guid messageId = System.Guid.NewGuid();
To see its value:
string x = messageId.ToString();
something = new Guid() equals something = Guid.Empty.
Use Guid.NewGuid(); instead
Guid g1 = Guid.NewGuid();
string s1;
s1 = g1.ToString();
Console.WriteLine("{0}",s1);
Console.ReadKey();
Related
I'm trying to parse my variable to its string representation typeName.
string typeName = property.PropertyType.ToString();
var propertyItem = (typeName)property.GetValue(templateData, null);
The string typeName should be the 'Type' of the property I have in my Model so somehow i want to parse it to that type. (at this moment it is List(InvoiceModel), but this may vary)
I hope this is enough information, otherwise please notify me. Thanks in advance.
property.GetValue returns the required object. From your code sample it seems that you don't know the object's type at compile time.
It is not possible to cast that object using (typename), and there is no use, because still you won't know the real type at compile time.
What you probably want to do is to use dynamic:
dynamic propertyItem = property.GetValue(templateData, null);
I think what you are looking for is property.GetType().ToString();
though you can't just put the varable in brackets to convert you need to use reflection to create the type
That said this entire idea is a bad idea, from the look of your code i think your trying to create some form of MetaData, if so then i would use an Enum to define your allowed datatypes, and i would only allow the simplest ones int, double, string, datetime etc and possibly an array's of such
in that case you would then do,
if(Property.Type == AllowedTyoes.String)
{
string stringval = Property.Value as string;
//use the string for a string safe function
}
if(Property.Type == AllowedTyoes.Int)
{
string stringval = Property.Value as string;
int tmp;
if(int.TryParse(stringval,out tmp))
{
//use the int for a int safe function
}
}
I'm adding a parameter to be called with a MySQL stored procedure like
List<MySqlParameter> MyParams = new List<MySqlParameter>();
MyParams.Add(new MySqlParameter("MyId", 0));
But for some reason when I look at MyParams, MyId value when stepping through my code, it is converted to null. Does anyone know why this is because if I assign the value from a int variable like below it is fine
int id = 0;
List<MySqlParameter> MyParams = new List<MySqlParameter>();
MyParams.Add(new MySqlParameter("MyId", id));
Well, You fell into the corner case of c# that literal 0 can be converted to Enum implicitly
An implicit enumeration conversion permits the decimal-integer-literal 0 to be converted to any enum-type
Reference
So, new MySqlParameter("MyId", 0) is compiled into MySqlParameter(string,MySqlDbType) rather than MySqlParameter(string,object) as the result your value 0 is ignored.
new MySqlParameter("MyId", id) this works because implicit conversions to enum works only when the value is literal not for variables. So It is clear that this gets compiled into MySqlParameter(string,object) resulting the expected results.
new MySqlParameter("MyId", (object)0)//this solves the problem
or this
New MySqlParameter("MyId", MySqlDbType.Int).Value = 0
BTW as #Suraj Singh pointed you may have to use #MyId instead of MyId.
Hope this helps
Use caution when you use this overload of the SqlParameter constructor to specify integer parameter values. Because this overload takes a value of type Object, you must convert the integral value to an Object type when the value is zero ---MSDN
Hope it's applicable for MySql too.
MyParams.Add(New MySqlParameter("#MyId", MySqlDbType.int)).Value = 0;
or try
Parameters.AddWithValue("#MyId", 0);
In your database schema, Is MyId a Primary Key of type int? with allow null set to yes?
assigning a value of 0 to a PK with allow null, will result in NULL being assigned.
I suspect its the database setup and not the code at fault.
I read values from an local Access mdb-file. One value is stored as string in the db and I have it in a table. When using the GetType() method it return "System.String" and I can print it on the console without a problem but when I want to use it as an attribute for another method (requires a string) I get an error ("Cannot convert from 'object' to 'string'" and the same for 'int'). The same problems occur with some int values.
Am I doing something wrong or what is the problem in that case?
Console.WriteLine(dt.Rows[0][ProjName]); //prints project_name
Console.WriteLine(dt.Rows[0][ProjName].GetType()); //print "System.String"
Project = new Project(dt.Rows[0][ProjName], dt.Rows[0][MinDay], dt.Rows[0][MinWeek], dt.Rows[0][DayWeek]); //Error
Project = new Project(Convert.ToString(dt.Rows[0][ProjName]), Convert.ToInt32(dt.Rows[0][MinDay]), Convert.ToInt32(dt.Rows[0][MinWeek]), Convert.ToInt32(dt.Rows[0][DayWeek])); //Works Fine
Constructor for the Project Class:
public Project(string projectName, int hoursPerDay, int hoursPerWeek, int daysPerWeek)
You have stated in your answer is works when converting, and it is necessary as they are not strings and integers. They are objects. You can create a methid to handle it if you want.
public Project CreateProject(object projectName, object hoursPerDay, object hoursPerWeek, object daysPerWeek)
{
return new Project(projectName.ToString(), Convert.ToInt32(hoursPerDay), Convert.ToInt32(hoursPerWeek), Convert.ToInt32(daysPerWeek);
}
You have to explicitly cast the objects:
To cast to string use:
Object.ToString();
To cast to integers use:
Int32.TryParse(String, out int);
Your constuctor becomes
Project = new Project(dt.Rows[0][ProjName].ToString(), Int32.Parse(dt.Rows[0][MinDay]), Int32.Parse(dt.Rows[0][MinWeek]), Int32.Parse(dt.Rows[0][DayWeek]));
Note: Using Int32.Parse instead of Int32.TryParse assumes that the argument provided is a valid int at all times and does not give you a way to check if the casting has succeeded.
dt.Rows[0][ProjName] returns type object, and your method expects string. Even though you know it to be a string, it is not obvious to the compiler and must be specified explicitly using a cast, as you show in your last example, although just casting should be more efficient than converting unnecessarily:
Project = new Project((string)dt.Rows[0][ProjName], ...
I'm getting the above error and unable to resolve it.
I googled a bit but can't get rid of it.
Scenario:
I have class BudgetAllocate whose property is budget which is of double type.
In my dataAccessLayer,
In one of my classes I am trying to do this:
double.TryParse(objReader[i].ToString(), out bd.Budget);
Which is throwing this error:
Property or indexer may not be passed as an out or ref parameter at
compile time.
I even tried this:
double.TryParse(objReader[i].ToString().Equals(DBNull.Value) ? "" : objReader[i].ToString(), out bd.Budget);
Everything else is working fine and references between layers are present.
Others have given you the solution, but as to why this is necessary: a property is just syntactic sugar for a method.
For example, when you declare a property called Name with a getter and setter, under the hood the compiler actually generates methods called get_Name() and set_Name(value). Then, when you read from and write to this property, the compiler translates these operations into calls to those generated methods.
When you consider this, it becomes obvious why you can't pass a property as an output parameter - you would actually be passing a reference to a method, rather than a reference to an object a variable, which is what an output parameter expects.
A similar case exists for indexers.
This is a case of a leaky abstraction. A property is actually a method, the get and set accessors for an indexer get compiled to get_Index() and set_Index methods. The compiler does a terrific job hiding that fact, it automatically translates an assignment to a property to the corresponding set_Xxx() method for example.
But this goes belly up when you pass a method parameter by reference. That requires the JIT compiler to pass a pointer to the memory location of the passed argument. Problem is, there isn't one, assigning the value of a property requires calling the setter method. The called method cannot tell the difference between a passed variable vs a passed property and can thus not know whether a method call is required.
Notable is that this actually works in VB.NET. For example:
Class Example
Public Property Prop As Integer
Public Sub Test(ByRef arg As Integer)
arg = 42
End Sub
Public Sub Run()
Test(Prop) '' No problem
End Sub
End Class
The VB.NET compiler solves this by automatically generating this code for the Run method, expressed in C#:
int temp = Prop;
Test(ref temp);
Prop = temp;
Which is the workaround you can use as well. Not quite sure why the C# team didn't use the same approach. Possibly because they didn't want to hide the potentially expensive getter and setter calls. Or the completely undiagnosable behavior you'll get when the setter has side-effects that change the property value, they'll disappear after the assignment. Classic difference between C# and VB.NET, C# is "no surprises", VB.NET is "make it work if you can".
you cannot use
double.TryParse(objReader[i].ToString(), out bd.Budget);
replace bd.Budget with some variable.
double k;
double.TryParse(objReader[i].ToString(), out k);
Possibly of interest - you could write your own:
//double.TryParse(, out bd.Budget);
bool result = TryParse(s, value => bd.Budget = value);
}
public bool TryParse(string s, Action<double> setValue)
{
double value;
var result = double.TryParse(s, out value);
if (result) setValue(value);
return result;
}
Place the out parameter into a local variable and then set the variable into bd.Budget:
double tempVar = 0.0;
if (double.TryParse(objReader[i].ToString(), out tempVar))
{
bd.Budget = tempVar;
}
Update: Straight from MSDN:
Properties are not variables and
therefore cannot be passed as out
parameters.
This is a very old post, but I'm ammending the accepted, because there is an even more convienient way of doing this which I didn't know.
It's called inline declaration and might have always been available (as in using statements) or it might have been added with C#6.0 or C#7.0 for such cases, not sure, but works like a charm anyway:
Inetad of this
double temp;
double.TryParse(objReader[i].ToString(), out temp);
bd.Budget = temp;
use this:
double.TryParse(objReader[i].ToString(), out double temp);
bd.Budget = temp;
So Budget is a property, correct?
Rather first set it to a local variable, and then set the property value to that.
double t = 0;
double.TryParse(objReader[i].ToString(), out t);
bd.Budget = t;
Usually when I'm trying to do this it's because I want to set my property or leave it at the default value. With the help of this answer and dynamic types we can easily create a string extension method to keep it one lined and simple.
public static dynamic ParseAny(this string text, Type type)
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null && converter.IsValid(text))
return converter.ConvertFromString(text);
else
return Activator.CreateInstance(type);
}
Use like so;
bd.Budget = objReader[i].ToString().ParseAny(typeof(double));
// Examples
int intTest = "1234".ParseAny(typeof(int)); // Result: 1234
double doubleTest = "12.34".ParseAny(typeof(double)); // Result: 12.34
decimal pass = "12.34".ParseAny(typeof(decimal)); // Result: 12.34
decimal fail = "abc".ParseAny(typeof(decimal)); // Result: 0
string nullStr = null;
decimal failedNull = nullStr.ParseAny(typeof(decimal)); // Result: 0
Optional
On a side note, if that's an SQLDataReader you may also make use of GetSafeString extension(s) to avoid null exceptions from the reader.
public static string GetSafeString(this SqlDataReader reader, int colIndex)
{
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
public static string GetSafeString(this SqlDataReader reader, string colName)
{
int colIndex = reader.GetOrdinal(colName);
if (!reader.IsDBNull(colIndex))
return reader.GetString(colIndex);
return string.Empty;
}
Use like so;
bd.Budget = objReader.GetSafeString(i).ParseAny(typeof(double));
bd.Budget = objReader.GetSafeString("ColumnName").ParseAny(typeof(double));
I had the same problem (5 minutes ago) and I solved it using old style properties with getter and setter, whose use variables.
My code:
public List<int> bigField = new List<int>();
public List<int> BigField { get { return bigField; } set { bigField = value; } }
So, I just used bigField variable. I'm not the programmer, if I misunderstood the question, I'm really sorry.
I have a DetailsView, I need get the value specifield in DataKeyNames "UserId" (a Guid Field) and add it to an Object Guid.
At the moment I am using this code:
String myUserId = (String)uxAuthorListDetailsView.DataKey["UserId"].ToString();
but I would need something like:
Guid myUserGuid = (Guid)uxAuthorListDetailsView.DataKey["UserId"].ToString();
But does not work I get error Error
Cannot convert type 'string' to 'System.Guid'
What could be the problem? Thanks guys for your support!
Well, the problem is that you're calling ToString() and then trying to cast that string to a Guid, when there's no such conversion available. Possible alternatives:
Cast instead of calling ToString(), if the original value is really a Guid:
Guid guid = (Guid)uxAuthorListDetailsView.DataKey["UserId"];
Parse the string instead:
Guid guid = new Guid(uxAuthorListDetailsView.DataKey["UserId"].ToString());
If this is user-entered data at all, or there's any other reason why the value is half-expected to be incorrect, and if you're using .NET 4, you might want to use Guid.TryParse instead, which will allow you to handle failure without an exception.
var myUserGuid = new Guid(uxAuthorListDetailsView.DataKey["UserId"].ToString());
Check under debug: what object is uxAuthorListDetailsView.DataKey["UserId"]
I guess this must be already the Guid; and conversion is not needed
Assuming uxAuthorListDetailsView.DataKey["UserId"] stores a valid Guid
try this
Guid myUserGuid = (Guid)uxAuthorListDetailsView.DataKey["UserId"]
remove ToString method