I suppose we all know that there are always some "ifs" and "buts". Edge Pereira wrote a blog post about a few of them that are related to human-human interaction. If I had to choose a single sentence from his post I would go for this one: "if an employee does not know the reason of his daily work, he will never wear the company's jersey". Needles to say I totally agree with the whole post.
Sunday, 24 February 2008
There is no perfect job
Friday, 15 February 2008
ReSharper 4 - nightly builds available at last
At this stage I nearly refuse writing code without ReSharper. I know it's bad but that's not the worst addiction ever :). Fortunately, JetBrians decided to release nightly builds of ReSharper 4 to public. Sweet.
Tags: ReSharper, Visual Studio
Tuesday, 12 February 2008
C# generics - parameter variance, its constraints and how it affects WCF
CLR generics are great and there is no doubt about that. Unfortunately, C# doesn't expose the whole beauty of it because all generic type parameters in C# are nonvariant though from CLR point of view they can be marked as nonvariant, covariant or contravariant. You can find more details about that topic here and here. In short the "nonvariant" word means that even though type B is a subtype of type A then SomeType<B> is not a subtype of SomeType<A> and therefore the following code won't compile:
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List<string> to 'System.Collections.Generic.List<object>. An explicit conversion exists (are you missing a cast?)
The generics are all over the place in WCF and you would think that this is always beneficial to all of us. Well, it depends. One of the problems I noticed is that you can not easily handle generic types in a generic way. I know it does not sound good :) but that's what I wanted to say. The best example is ClientBase<T> that is the base class for auto generated proxies. VS.NET generates a proxy type per contract(interface) which might lead to a situation where you need to manage quite a few many different proxies. Let's assume that we use username and password as our authentication method and we want to have a single place where the credentials are set. The method might look like the one below: public void ConfigureProxy(ClientBase<Object> proxy) { proxy.ClientCredentials.UserName.UserName = "u"; proxy.ClientCredentials.UserName.Password = "p"; } Unfortunately we can't pass to that method a proxy of type ClientBase<IMyContract> because of nonvariant nature of C# generics. I can see at least two options how to get around that issue. The first one requires you to clutter the method with a generic parameter despite the fact that there is no use of it.
Approach based on a non-generic interface:
Having that hierarchy in place we could define our method in the following way:
Unfortunately WCF architects haven't thought about that and a non-generic ClientBase/IClientBase class/interface doesn't exist. The interesting part of this story is that the FaultException<T> class does not suffer from the same problem because there is a non-generic FaultException class that exposes all the non-generic members. The FaultException<T> class basically adds a single property that returns the detail of the fault and that's it. I can find more classes that are implemented in exactly the same way FaultException<T> is implemented. It looks like ClientBase<T> is the only one widely used class that breaks that rule. I would love to see this inconvenience fixed as an extension of C# parameter variance.
List <String> stringList = null;
List <object> objectList = stringList; //this line causes a compilation error
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List<string>
The generics are all over the place in WCF and you would think that this is always beneficial to all of us. Well, it depends. One of the problems I noticed is that you can not easily handle generic types in a generic way. I know it does not sound good :) but that's what I wanted to say. The best example is ClientBase<T> that is the base class for auto generated proxies. VS.NET generates a proxy type per contract(interface) which might lead to a situation where you need to manage quite a few many different proxies. Let's assume that we use username and password as our authentication method and we want to have a single place where the credentials are set. The method might look like the one below: public void ConfigureProxy(ClientBase<Object> proxy) { proxy.ClientCredentials.UserName.UserName = "u"; proxy.ClientCredentials.UserName.Password = "p"; } Unfortunately we can't pass to that method a proxy of type ClientBase<IMyContract> because of nonvariant nature of C# generics. I can see at least two options how to get around that issue. The first one requires you to clutter the method with a generic parameter despite the fact that there is no use of it.
public void ConfigureProxy <T>(ClientBase <T> proxy) where T : classYou can imagine I'm not big fun of this solution. The second one is based on the idea that the non-generic part of the public interface of ClientBase class is exposed as either a non-generic ClientBase class or a non-generic interface IClientBase. Approach based on a non-generic class:
{
proxy.ClientCredentials.UserName.UserName = "u";
proxy.ClientCredentials.UserName.Password = "p";
}
public abstract class ClientBase : ICommunicationObject, IDisposable
{
public ClientCredentials ClientCredentials
{
//some code goes here
}
}
public abstract class ClientBase <T> : ClientBase where T : class
{
}
Approach based on a non-generic interface:
public interface IClientBase : ICommunicationObject, IDisposable
{
ClientCredentials ClientCredentials { get; }
}
public abstract class ClientBase <T> : IClientBase where T : class
{
}
Having that hierarchy in place we could define our method in the following way:
public void ConfigureProxy(ClientBase/IClientBase proxy)
{
proxy.ClientCredentials.UserName.UserName = "u";
proxy.ClientCredentials.UserName.Password = "p";
}
Unfortunately WCF architects haven't thought about that and a non-generic ClientBase/IClientBase class/interface doesn't exist. The interesting part of this story is that the FaultException<T> class does not suffer from the same problem because there is a non-generic FaultException class that exposes all the non-generic members. The FaultException<T> class basically adds a single property that returns the detail of the fault and that's it. I can find more classes that are implemented in exactly the same way FaultException<T> is implemented. It looks like ClientBase<T> is the only one widely used class that breaks that rule. I would love to see this inconvenience fixed as an extension of C# parameter variance.
Saturday, 9 February 2008
Dublin Bus Executives, see how far behind you are
Saturday, 2 February 2008
Looking for Quality not Quantity
I'm sure you've already heard opinions that the wide opening of weblogs.asp.net might not be a good thing because it lowers the overall quality of the portal. I can see more often then before that people are leaving that site. I'm not saying that the aforementioned change caused that but something is going on.
When I started blogging I wanted to have a blog on weblogs.asp.net but the admin replied to me that they didn't have any "free slots". At that time I was a little bit upset about that but now I know that his decision was right. Basically in most cases before you are able to provide interesting content you need to familiarize yourself with all the stuff that's already out there. Reinventing the wheel is not interesting and learning (climbing predecessors' shoulders) is not easy.
Current status: Climbing :).
When I started blogging I wanted to have a blog on weblogs.asp.net but the admin replied to me that they didn't have any "free slots". At that time I was a little bit upset about that but now I know that his decision was right. Basically in most cases before you are able to provide interesting content you need to familiarize yourself with all the stuff that's already out there. Reinventing the wheel is not interesting and learning (climbing predecessors' shoulders) is not easy.
Current status: Climbing :).
Subscribe to:
Posts (Atom)