Pokazywanie postów oznaczonych etykietą c#. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą c#. Pokaż wszystkie posty

niedziela, 21 marca 2010

System.String and new() constraint

Few days ago, my colleague was dealing with code that was loading a list of objects from DataReader. Basically, for every record, a new object was created like this:
T obj = new T();
//set some properties using reflection
result.Add(obj);
Of course, the method had new() constraint for type T. The method name was pretty generic, however the method couldn't handle scalar values like ints, floats, etc. (because it tried to set some properties through reflection). My colleauge changed the code and if the value was a scalar value (IsPrimitive seemed ok for us) the value from reader was casted to T and assigned to obj. My colleague mentioned that this method won't work for String because String doesn't have public parameterless constructor. To be honest, I didn't know that because I have never needed to write something like String str = new String(). I've always written String str = String.Empty. However, it seems really odd that you can't just say new String(). I asked about this issue on stackoverflow: http://stackoverflow.com/questions/2454914/system-string-why-doesnt-it-implement-parameterless-constructor.
I suggest you read this post. Discussion in answers is really interesting.

I asked this question and thought about this issue for few hours. In our particular case, the code was clearly wrong. We created another method for scalar values without new() constraint. However, I still think that lack of public parameterless constructor for System.String is a .NET flaw (yet, as I said, I have never had a need to use it ;)).

poniedziałek, 30 listopada 2009

Developer checklist

Every book about project managament in software industry starts with some sad statistics that sound something like this:
According to the Standish Group in 1995, only about 16% of software projects are successful, 53% challenged (that is cost overruns, budget overruns or content deficiencies) and 31% cancelled.
http://www.projectsmart.co.uk/why-software-projects-fail.html

Sometimes I think that it's just an excuse for incompetent project managers but let's assume that's sad true about software industry.
However, I must say that most software projects I worked on were successful in terms of customer paying for delivered software. I must admit that I've worked only in software houses and even if a client wasn't delighted he had to pay for the product.
As a developer, I'm not responsible for selling the product, I'm responsible for software architecture, maintainability and so on. From this point of view, many projects were huge failures. I don't have recipe for making successful software, but I know what leads to failure. If you don't follow this simple rules you will inevitably have lots of problems.
The rules are kind of best practices. I divided them in several sections ordered by their importance.

MUST-FOLLOW rules
  1. Use version control system and more importantly learn how to use it.
    For example, if you work with SVN learn how to create branches, add properties, always write comments when commiting changes.
  2. Create centralized error/exception handlers.
    I've seen so many projects that don't utilise this functionality. Distinguishing mark of such project is the need that every developer has to remember to catch exceptions in their routines, even though they mostly don't know what to do with them.
  3. Log information about errors.
    This is connected with previous point but I want to emphasize proper error logging facility. Too many times I've seen code like this:
    public void LogException(Exception ex)
    {
        Logger.Error(ex.Message);
    }
    
    or:
    try
    {
        /* some code */
    }
    catch (Exception ex)
    {
        Logger.Error("Something bad happened");
    }
    
    If you don't know what really happened, you won't be able to deal with it. Remember, most errors will occur when application goes to production environment, not during debugging sessions.
  4. Keep security in mind.
    If you work with sql database never ever let sql injection be possible in your app. If you work with directory service watch out for ldap injection. If you create web service - secure it. Never trust user input and never assume anything about the environment your app will be working in (or assume the worst).
  5. Understand SOA if you really want to use it
    Service oriented architecture is very hard to implement properly. Many times people end up creating service that has thousands of completely unrelated methods or service that can take every argument and return every result. This is a real maintaince nightmare. What is more, if you publish your service definition it is almost impossible to change it without making breaking change. Services should be really well defined and many times it is just not the way to go. If you really don't need to publish some services to third parties don't do it.
  6. Create good testing environment.
    If you don't have testing environment that is very similar to production environment you will fail. Deployment in production environment will be a nightmare and you will not meet your deadlines. I assure you.

SHOULD-FOLLOW rules
  1. Don't mix presentation layer with application logic.
    It is repeated over and over but it seems that people will never learn. Sometimes it seems to be easier to put some logic in presentation layer but it is always bad decision.

MAY-FOLLOW rules
  1. Unit testing / automated tests.
    Personally I consider it to be very important, but I've seen many projects that were well-written and had great architecture even though they didn't contain single unit test. What is more, they had almost no bugs. That's why I put unit tests only on "may" list.

These are my rules of creating software that has smaller chance of failure. Every time I forget rules from my "must" list I have serious problems. To be honest, few times I tried just to forget these rules and tried to create some workarounds because I considered implementing e.g. central error handling a breaking change to the code. However, I always ended up fixing it because breaking the rule had such a bad impact on the application. I've learnt from these examples that creating workarounds is just a waste of time. Unfortunately, it was learning the hard way. I hope you will find the list helpful.
Happy coding.

sobota, 10 października 2009

I am the key to the lock in your house or some thoughts about reflection and Singleton pattern

I wanted to present some thoughts about the Singleton pattern and assumptions you can make about it. This post also shows that using reflection is like going to the darkside ;)

Say, we have a class SingletonFoo that manipulates some PreciousResource. Access to PreciousResource must be synchronized and manipulation should be performed in critical section.
public class SingletonFoo : ObjectWithIdentifier
{
    private static int instancesCount;
    private static PreciousResource preciousResource = new PreciousResource();
    private static SingletonFoo instance = new SingletonFoo();        

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static SingletonFoo() { }
    
    private SingletonFoo()
    {
        instancesCount++;
    }

    public static SingletonFoo Instance { get { return instance; } }        

    public void ManipulatePreciousResource()
    {
        // no need for locking, we are in a singleton!            
        Console.WriteLine("{0} is accessing the resource {1}", this, preciousResource);
        preciousResource.Manipulate();
    }

    public override string ToString()
    {
        return String.Format("{0} [instances count: {1}]", base.ToString(), instancesCount);
    }
}
For clarification here is ObjectWithIdentifier:
public class ObjectWithIdentifier
{
    private Guid uniqueId = Guid.NewGuid();
    public Guid UniqueId { get { return uniqueId; } }

    public override string ToString()
    {
        return String.Format("{0}, id: {1}", this.GetType().Name, uniqueId);
    }
}
ObjectWithIdentifier is only necessary for giving more meaningful output from the application.
We have a situation when someone creates Singleton and assumes that he may be sure that only one instance of this class exists in the system, so he doesn't have to synchronize access to some PreciousResource:
public class PreciousResource : ObjectWithIdentifier
{
    public void Manipulate()
    {
        //do something
    }
}
However, here comes the evil doer:
public static class EvilBar
{
    const int REPEAT_COUNT = 2;

    public static void BeNice()
    {
        Console.WriteLine("Now I'm nice");
        for (int i = 0; i < REPEAT_COUNT; i++)
        {
            SingletonFoo.Instance.ManipulatePreciousResource();
        }
    }

    public static void BeEvil()
    {
        Console.WriteLine("Now I'm evil!");
        for (int i = 0; i < REPEAT_COUNT; i++)
        {
            ((SingletonFoo) Activator.CreateInstance(typeof(SingletonFoo), true)).ManipulatePreciousResource();
        }
    }
}
When EvilBar is nice we get following output:
Now I'm nice

SingletonFoo, id: 7dbccd1c-4e74-4e1d-b762-104f4cbcb82b [instances count: 1] is accessing the resource PreciousResource, id: c2b4a8b7-80e8-46cf-b616-a3f45f0612d7
SingletonFoo, id: 7dbccd1c-4e74-4e1d-b762-104f4cbcb82b [instances count: 1] is accessing the resource PreciousResource, id: c2b4a8b7-80e8-46cf-b616-a3f45f0612d7
But what happens if EvilBar is trully evil:
Now I'm evil!

SingletonFoo, id: 5a829a65-580f-4cc2-b17b-2650f68e464b [instances count: 2] is accessing the resource PreciousResource, id: 8417a76b-a40b-4221-bd73-0b507ff059c9
SingletonFoo, id: 744eba58-9aa9-4ee2-97aa-ffd815c3832f [instances count: 3] is accessing the resource PreciousResource, id: 8417a76b-a40b-4221-bd73-0b507ff059c9
We have three instances of our Singleton class. One for singleton and two instance created with Activator.
Ok, the class was intentionally written to be evil. But was XmlSerializer written to be evil? Let's add another method to EvilBar:
public static void BeUnwittlinglyEvil(SingletonFoo foo)
 {
    Console.WriteLine("Now I'm unwittingly evil");
    Console.WriteLine("Foo before operations: {0}", foo);

    XmlSerializer serializer = new XmlSerializer(typeof(SingletonFoo));

    StringBuilder serialized = new StringBuilder();
    using (StringWriter sw = new StringWriter(serialized))
    {                
        serializer.Serialize(sw, foo);
    }

    SingletonFoo result;
    using (StringReader sr = new StringReader(serialized.ToString()))
    {
        result = (SingletonFoo) serializer.Deserialize(sr);
    }

    result.ManipulatePreciousResource();
}
After executing the method EvilBar.BeUnwittlinglyEvil(SingletonFoo.Instance), we get following output:
Now I'm unwittingly evil

Foo before operations: SingletonFoo, id: 5c4724bb-ac02-4300-9be6-70c86c5629fc [instances count: 1]
SingletonFoo, id: 58612540-6d6a-458a-8c0c-1f723117f9b6 [instances count: 2] is accessing the resource PreciousResource, id: e7a55b7f-4e62-4d1f-878c-499ec0387a31
The implementation looks weird, but that just an example what happens if someone serializes this class and then unserializes it. If the code is executed in different threads, you will run into synchronization issues.
In Pragmatic Programmer there is a nice quiz. Which of these things should never happen (answers are presented below the post):
1. A month with fewer than 28 days
2. stat("." ,&sb) == -1 (that is, can't access the current directory)
3. In C++: a = 2; b = 3; if (a + b != 5) exit(1);
4. A triangle with an interior angle sum \u8800 180°
5. A minute that doesn't have 60 seconds
6. In Java: (a + 1) <= a

I'm adding another thing to the list: singleton with more than one instance ;)
The point is, you always have to think about the things you can be sure about your code and about the ways people are using your code. The less you assume, the better.


List of things that should never happen:
1. September, 1752 had only 19 days. This was done to synchronize calendars as part of the Gregorian Reformation.
2. The directory could have been removed by another process, you might not have permission to read it, &sb might be invalid—you get the picture.
3. We sneakily didn't specify the types of a and b. Operator overloading might have defined +, =, or ! = to have unexpected behavior. Also, a and b may be aliases for the same variable, so the second assignment will overwrite the value stored in the first.
4. In non-Euclidean geometry, the sum of the angles of a triangle will not add up to 180°. Think of a triangle mapped on the surface of a sphere.
5. Leap minutes may have 61 or 62 seconds.
6. Overflow may leave the result of a + 1 negative (this can also happen in C and C++).

sobota, 3 października 2009

Syntax sugar, aop and things that mess up with you behind the scenes

The more I play with reflector, the more my head aches ;)
Suppose we have a simple class like this one:
class TestClass
{
public void SomeMethod()
{
Console.WriteLine("doing something");
}

public void SomeMethodWithArgs(int arg)
{
Console.WriteLine("doing something with arg {0}", arg);
}

public string SomeMethodWithArgsAndReturn(int arg, string str)
{
Console.WriteLine("again doing something");
return String.Format("result ({0} + {1} = <foobar>", arg, str);
}

public IEnumerable<int> SomeIteratorMethod()
{
int counter = 0;
while (counter++ < 3)
{
yield return 2 * counter + 3;
}
}
}
When I look at SomeMethodWithArgsAndReturn, in reflector it looks like this:
public string SomeMethodWithArgsAndReturn(int arg, string str)
{
Console.WriteLine("again doing something");
return string.Format("result ({0} + {1} = <foobar>", arg, str);
}
Cool, huh?
First three methods look the same in reflector and in code. But what about SomeIteratorMethod? It has that fancy yield statement. Well, it looks like this:
public IEnumerable<int> SomeIteratorMethod()
{
<someiteratormethod>d__0 V_0 = new <someiteratormethod>d__0(-2);
V_0.<>4__this = this;
return V_0;
}
I also have a new class:
[CompilerGenerated]
private sealed class <someiteratormethod>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
// Fields
private int <>1__state;
private int <>2__current;
public TestClass <>4__this;
private int <>l__initialThreadId;
public int <counter>5__1;

// Methods
[DebuggerHidden]
public <someiteratormethod>d__0(int <>1__state);
private bool MoveNext();
[DebuggerHidden]
IEnumerator<int> IEnumerable<int>.GetEnumerator();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
void IEnumerator.Reset();
void IDisposable.Dispose();

// Properties
int IEnumerator<int>.Current { [DebuggerHidden] get; }
object IEnumerator.Current { [DebuggerHidden] get; }
}
I've hidden implementation but that's just an implementation of an iterator. However, that's a lot of code compared to my simple yield statement.
Some time ago my friend said that he doesn't like most of the new c# 3.0 features (ok, yield was added in c# 2.0 but that's not the point) because that's just syntactic sugar and he wants to know what happens behind the scenes. My opinion was that I don't maintain msil/byte code so I don't care what happens behind the scenes.
BUT maybe i DO care? This post by Eric Lippert clearly shows that I care or at least I should ;)
Ok, that's an example of a compiler doing something behind the scenes, but what if we want to mess up with the code ourselves? Concept of aspect oriented programming and aspect weaver is this kind of messing up with code.
Let's look at PostSharp and create a basic example of logging of entry and exit to the method body. I've created a simple trace attribute using PostSharp:
[Serializable]
public class TraceAttribute : OnMethodBoundaryAspect
{
private void LogMethod(string beginning, MethodExecutionEventArgs eventArgs)
{
StringBuilder result = new StringBuilder();
result.Append("== ");
result.Append(beginning);
result.AppendFormat(" {0}.{1}(", eventArgs.Method.DeclaringType.Name, eventArgs.Method.Name);
//imma charging mah oneliner ;)
result.Append(String.Join(",", (from arg in eventArgs.GetReadOnlyArgumentArray() ?? new object[0] select String.Format("[{0}]", Convert.ToString(arg))).ToArray()));
result.AppendFormat(") -> [{0}]", eventArgs.ReturnValue);
result.Append(" ==");
Console.WriteLine(result.ToString());
}

public override void OnEntry(MethodExecutionEventArgs eventArgs)
{
LogMethod("Entering", eventArgs);
}

public override void OnExit(MethodExecutionEventArgs eventArgs)
{
LogMethod("Leaving", eventArgs);
}
}
I've added TraceAttribute to SomeMethodWithArgsAndReturn:
[TraceAttribute]
public string SomeMethodWithArgsAndReturn(int arg, string str)
{
Console.WriteLine("again doing something");
return String.Format("result ({0} + {1} = <foobar>", arg, str);
}
In the end when I run my app with:
(new TestClass()).SomeMethodWithArgsAndReturn(11, "twelve");
I get nice output:
== Entering TestClass.SomeMethodWithArgsAndReturn([11],[twelve]) -> [] ==
== Leaving TestClass.SomeMethodWithArgsAndReturn([11],[twelve]) -> [result (11 + twelve = <foobar>] ==
But now my simple method in reflector looks completely different:
public string SomeMethodWithArgsAndReturn(int arg, string str)
{
string ~returnValue~1;
MethodExecutionEventArgs ~laosEventArgs~4;
try
{
object[] ~arguments~3 = new object[] { arg, str };
~laosEventArgs~4 = new MethodExecutionEventArgs(<>AspectsImplementationDetails_1.~targetMethod~1, this, ~arguments~3);
<>AspectsImplementationDetails_1.PostSharpTest.TraceAttribute~1.OnEntry(~laosEventArgs~4);
if (~laosEventArgs~4.FlowBehavior == FlowBehavior.Return)
{
return (string) ~laosEventArgs~4.ReturnValue;
}
Console.WriteLine("again doing something");
string CS$1$0000 = string.Format("result ({0} + {1} = <foobar>", arg, str);
~returnValue~1 = CS$1$0000;
~laosEventArgs~4.ReturnValue = ~returnValue~1;
<>AspectsImplementationDetails_1.PostSharpTest.TraceAttribute~1.OnSuccess(~laosEventArgs~4);
~returnValue~1 = (string) ~laosEventArgs~4.ReturnValue;
}
catch (Exception ~exception~2)
{
~laosEventArgs~4.Exception = ~exception~2;
<>AspectsImplementationDetails_1.PostSharpTest.TraceAttribute~1.OnException(~laosEventArgs~4);
switch (~laosEventArgs~4.FlowBehavior)
{
case FlowBehavior.Continue:
return ~returnValue~1;

case FlowBehavior.Return:
return (string) ~laosEventArgs~4.ReturnValue;
}
throw;
}
finally
{
~laosEventArgs~4.ReturnValue = ~returnValue~1;
<>AspectsImplementationDetails_1.PostSharpTest.TraceAttribute~1.OnExit(~laosEventArgs~4);
~returnValue~1 = (string) ~laosEventArgs~4.ReturnValue;
}
return ~returnValue~1;
}
Wow!
Once again, I've got much more code but it's not in my source code. And once again do I maintain that code? Do I have to be aware of it? How much do I have to know about it?
So the answer can be: don't use any syntactic sugar, don't use aop. You're fine with your strings, ints and simple stuff. You understand how they work and you're cool with it. Are you? Did you know e.g. about this: String interning and String.Empty?
Eric Lippert's blog Fabulous Adventures In Coding is full of these stories. And just wait for c# 4.0 - Evil code of the day.

Time for final remarks or maybe just my opinion on this topic.
I really like syntactic sugar and I'm keen on learning aop concepts. The things I wrote about in this post are scary to me but I think we just have to deal with the fact that computer languages are complicated (even if they try to hide it) and concepts that are simple in everyday work hide their complexity behind the scenes. Look at c#. You've got transformation between c# and msil, you've got jit, clr executing all that stuff and somewhere deep, deep below the code you've written there are pure assembly instructions. Syntax sugar doesn't introduce that much complexity compared to all the other stuff that happens implicitly and we don't (have to ;)) know about.
Remember, there's no such thing as free lunch ;)

piątek, 21 sierpnia 2009

PHP MVC vs. C# ASP.NET or the cure is worse than the evil

I started programming using C++.
Then I was writing stuff in C, C++, Pascal, Java, C#.
When I wanted to get my first job I figured out that most students work as PHP programmers, so I borrowed a book about PHP, wrote a sample application and a month later I was a PHP programmer.
I must say that in the beginning I hated every single bit of PHP. I've never written an app that I din't have to compile in order to run it. These crazy PHP constructs such as $$. Wow, they're really crazy.
What is more, I have never written a web application before. I always wrote some console / desktop stuff.
However, after about 3 months of coding on a daily basis I was pretty comfortable with almost everything I was doing. Maybe not with PHP itself, to be honest - I have never become comfortable with this language, but whole MVC pattern and its connection with web interface is so intuitive and natural that it really became my world. I still think that navigation on web pages is far better than navigation in desktop applications. When everything is identified by URL and I can open every link in another tab, I feel comfortable with interface. When I have lots of buttons and no tabs to open, I feel crippled with interface.
When I see a link like /article/show/123 or /article/edit/123 and I have Article controller and methods like show or edit, I can just sit and write code I need. I just love that HTTP protocol is stateless. I love the fact that anyone who clicks the link, be it a real user or google crawler, sees (almost) the same content.
PHP also has great template frameworks, such as Smarty. It's very intuitive and readable. The most important this is that THAT guys ;) don't have problems working with it and can easily can change the markup without affecting application logic.
Even though PHP frameworks like Cake and basically all MVC frameworks are very intuitive (in fact we were using our own MVC framework), language that drives them is really crappy. I've seen lots of PHP code, even very good PHP, and I've never seen good object-oriented patterns. Yes, there were lots of classes, but concepts such as inheritance, static objects, interfaces or abstract classes are not a part of this world. Classes in php are quite important but they are not strongly related to each other. When I think of real OO classes, I think about inheritance, interfaces that they implement, I see that some of them are more specialized, while others represent some general ideas. PHP OO in my opinion is poor man's OO. The real power in php are its associative arrays.
If I ranted about PHP flaws in its implementation of OO and wouldn't say that I was a strong advocate of not using most of its features in PHP5, I would be very unfair with people developing this language. I was always a strong opponent of using private / public keywords. The main reason was that every time someone messed up with it, we got white page of death on production server. I consider private / public modifiers to be important while compiling the code, but they become completely unimportant during runtime. Even if you declare field to be private, you can still access it using reflection of some kind. In php, when you don't declare types of method arguments, concepts such as interfaces also don't mean anything. PHP function takes basically anything and then tries to execute some methods on it. You don't have to declare interface to be able to execute some particular method on a given object. Well, you just try to execute it.
I worked with php programmers who actually used to think about types of objects they passed to functions. All interface / abstract stuff WAS implemented in the logic but not in terms of keywords. It was convention over configuration, and it worked pretty well.
Unfortunately, when someone didn't want to keep the convention, we just couldn't force them to keep it. And hell yeah, I wanted all people using my code to pass only some particular interfaces as arguments. I was unable to do that.
To sum up, I think that PHP is crappy, but it has great MVC frameworks, nice templating systems and if you want, you can write really good code in it.

On the other hand, there are C# and ASP.NET. I must say that I just love C# 3.0. It has so many useful features, great attributes, lambda expressions, generics. Some things could be better in C# 4.0, but even now it is my language of choice. C# lets you write clean and descriptive code that you would not be able to write in PHP.
However, here comes ASP.NET. I'm not talking about ASP.NET MVC - I have no experience with it, I'm talking particularly about classic ASP.NET. Well, ASP.NET is such a poor abstraction that I still cannot understand how someone came up with this idea. The whole concept of WebForms is really far from what web is really about. How could they come up with a lifecycle like that: page lifecycle (click to see the picture). Honestly, how could anyone make such an unintuitive life cycle and say that it is easier for web programming because it's like WinForms programming?
Most ASP.NET developers think that ViewState and Session are perfectly good places for keeping variables responsible for page navigation. Yeah, it's so great when you click on a page and URL doesn't change. It's so easy to share content with other users. Crawlers also love it! And what is really cool, sometimes you have to debug your application to see what are your current arguments and then you may find out that e.g. you forgot to clear Session in some onclick event.
And the whole gridview thing. That's a neat idea. Take everything from any datasource you have (e.g. 10 million records from a database) and do all things like filtering, sorting, paging, etc. yourself! Furthermore, keep all data in ViewState.
Seriously, how could anyone come up with that?
Everybody knows that webpage is like a real desktop application and all actions should be seen as events, e.g. click. Everyone agrees? Great.
Templating engine? We will show how hard could that be. Even tags are messed up: inline tags.
Crossbrowser issues? Only in asp.net. Yeah, there are lots of controls that work in IE, but don't work in FireFox.
Someday, I will come back to asp.net issue. In this post I just wanted to show how crappy it is. In my opinion, when you write web apps in php, ruby or python, you feel that you're writing for the web. When you use ASP.NET, you're writing these stupid webforms.
To sum up, C# - great, ASP.NET - yuck.

And here comes the final conclusion.
If I had to write a web application that goes public (not some intranet application) I would choose...


... PHP + MVC. I'm really sure that the result would be far better using that technology.

If I had to choose a job and I could choose between using these two technologies I would choose...


... C# + ASP.NET. It's better paid and you have chances that you'll be writing some underlying layer in C# and you don't have to deal with ASP.NET.

I must check this ASP.NET MVC stuff. I hope it will solve all issues of classic ASP.NET.
Remember kids, choose the right tools for the job and keep in mind that all that glitters is not gold ;)
Q.E.D., Bitches!