sobota 16. října 2010

int == System.Int32. Or not?

So they say int is an alias to System.Int32, right? So I should be able to use one where ever I use the other, right? Or not?

Try this:


public enum AddressTypes : System.Int32 { Delivery = 1, Invoicing = 2};



==>

Error 89 Type byte, sbyte, short, ushort, int, uint, long, or ulong expected D:\...\DataModel\DB.Designer2.cs 799 34 DataModel

Oh Microsoft, how I love thee.
So the Entity Framework dutifully converts the database type to the .Net type, I take the type, use it in generated code and kaboooom. Thank you!

void Dictionary.Add(TK key, TV value)

Oh my. Why the heck could not they let this method return the dictionary being added to? Why?

Not only I could write

aLongAndComplicatedDictionaryName
    .Add("foo", foo)
    .Add("bar", bar);

but ... more importantly ... I would not have to jump through hoops as soon as I need to add one more key into a dictionary createdy by .ToDictionary() in the middle of a complex LINQ query.

Oh well.

úterý 12. října 2010

IsNumeric is not numeric (MS SQL)

Run this on MS SQL (2008 RC2, but I don't think the version matters):


select isnumeric('.')
select convert(int,'.')

Sweet isn't it? And no, it's not because integers are not supposed to have a decimal dot.

select convert(float,'.')

explodes too. 
Let's continue the fun.

select isnumeric('-')

returns 1.

select convert(int,'-')

returns 0 and

select convert(float,'-')

explodes. Why???

On the other hand

select convert(int, '14.878')

explodes, while

select convert(int, convert(float,'14.878'))

returns 14.

pondělí 11. října 2010

AttributeProviderAttribute rendered useless ... or maybe not?


OK, so I'm writing some ASP.Net MVC application, I've got some data model classes generated by Entity Framework (with a custom template and loads of attributes added to the properties) and of course for the views I've got some viewmodels. Nothing unusual right? Most of the properties of the viewmodels are of course based on the properties of the datamodel so I'd like to copy the attributes from the datamodel classes to the viewmodel classes so that instead of repeating the loads of attributes I could just point to the other property in the other class and have them copied.
Enter System.ComponentModel.AttributeProviderAttribute. The docs are rather bad, babbling something unrelated about some silly DataGridView.DataSource property, but nevertheless it looks like it might be the thing I'm looking for. Let's see ... so you can specify the type to get the attribute from as [AttributeProvider(typeof(Project.Models.Whatever)], you can also specify the type name as a string ("The name of the type to specify." per docs, with no example whatsoever) or you can specify the type name as string and the property name as string (again, no examples).

OK, I need to specify the property name, so I have to use the AttributeProviderAttribute(String, String) constructor.

public class Sumfin {
 [AttributeProvider("Project.Models.Whatever", "FullName"]
 public string Name {get;set;}
 ...

Nope, no chance. No error, but the attributes are not there. OK, let's see if I can get it to take the attributes from the type itself.
[AttributeProvider("Project.Models.Whatever"]
Nope. OK, let's try the other syntax ...
[AttributeProvider( typeof(Project.Models.Whatever)]
Hey, that works. But how the heck do I specify the property?? And why doesn't the string version of the type name work?

A few Google searches later ... I need what?!? An assembly qualified name of the type? What the fsck is that?

OK, typeof(Project.Models.Whatever).AssemblyQualifiedName returns the thing. Something like  "Project.Models.Whatever, DataModel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null". Lovely. And
[AttributeProvider( typeof(Project.Models.Whatever).AssemblyQualifiedName, "FullName"] of course doesn't work: "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type".

Thank you very much Microsoft! It would be too much work to provide a fourth constructor AttributeProviderAttribute(Type, String), right?

OK. The docs say that AttributeProviderAttribute class cannot be inherited, but what if I try??

public class BasedOnAttribute : AttributeProviderAttribute {
public BasedOnAttribute(Type type, string property)
: base(type.AssemblyQualifiedName, property) {
}
}

[BasedOn( typeof(Project.Models.Whatever), "FullName"]
public string Name {get;set;}

Build, run ... hey, it works and does what I wanted all along! What does the "This class cannot be inherited." in the AttributeProviderAttribute class mean then? Never mind. I got my cookie.