Skip to main content

ObsoleteAttribute and the Expression Compiler

I was going to post this as a question over at SO, but as I got to the end I realised a blog would probably be better (apart from the fact that only five people will read it!).

The project I'm working uses runtime objects that are produced with configuration-driven delegates built using Expression trees.

I'm doing a big functionality merge at the moment and have reached a class that, because of another that has grown, is now obsolete. So I want to make it 'properly' obsolete (generate compiler errors), go through the static codebase and change all the references.

The problem is that the class library is used, through Expressions, by a few other apps so I can't yet get rid of the class completely - I'll perhaps look at farming that job off to somebody else.

So I thought I'd just check whether the expression compiler honours the ObsoleteAttribute when marked as an error, and it doesn't:

[TestClass]
public class UnitTest1
{
    [Obsolete("obsolete", true)]
    public class ObsoleteClass
    {

    }

    [TestMethod]
    public void TestObsoletedClassViaExpression()
    {
        Type obsoleteType = typeof(UnitTest1).GetNestedType("ObsoleteClass");

        Func<object> f =
            Expression.Lambda<Func<object>>(
                Expression.New(obsoleteType)
            ).Compile();

        var o = f();

        Assert.AreEqual(obsoleteType, o.GetType());
    }
}

In my case this is actually an advantage as it means the existing projects will carry on working with the updated codebase since the only reference to this type will be through dynamically generated code.

Of course once I finally remove the type those apps will no longer work - but I won't do that until they've all been updated. That said, it would be a lot easier to go through these apps an augment them to the replacement type if the Expression compiler *did* honour the ObsoleteAttribute - just follow the runtime errors (! - sorry I mean run the tests of course ;) ).

I understand, and have exploited, the fact that the Expression compiler is allowed to do things that aren't normal - skip visibility checks etc. I also understand that attributes such as ObsoleteAttribute require a compiler to honour them as, at the IL level, they are meaningless.

However, given Extression trees' ubiquity and growing importance, shouldn't its compiler honour (or have the option to honour) the ObsoleteAttribute? On the DLR, for example, this means that a language designer must code in reflection at every step to look for Obsolete(true) declarations if he/she wants to have this functionality in their language.

Like I say, it’s a tricky one because in this particular example it’s going to work in my favour – I’m just not sure it should.

Comments

Popular posts from this blog

Asp.Net 2 and 4 default application pool generates CS0016 IIS7.5

Before I start – if you’ve found a bunch of other articles about this around the net, tried the fixes that are mentioned and still not getting any joy – then read on – you might find this solves your problem. Earlier today I discovered that when I run any ASP.Net 2 or 4 application through IIS7.5 using the default application pools (which use ApplicationPoolIdentity) on Windows 2008 R2 x64 I get an error message similar to this:   Server Error in '/MvcApplication31' Application. Compilation Error Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. Compiler Error Message: CS0016: Could not write to output file 'c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\mvcapplication31\222b4fe6\4e80a86\App_global.asax.clb4bsnc.dll' -- 'The directory name is invalid. ' Source Error: [No relevant source ...

Serializing to attributes in WCF with DataContractSerializer

It’s a common problem – you want to return an object from a WCF service as XML, but you either want, or need, to deliver some or all of the property values as XML Attributes instead of XML Elements; but you can’t because the DataContractSerializer doesn’t support attributes (you’re most likely to have seen this StackOverflow QA if you’ve done a web search).  Most likely you’ve then migrated all your WCF service code to using the XmlSerializer (with all the XmlElement/XmlAttribute/XmlType attributes et al) – and you’ve cursed loudly. Well, I’m here to rescue you, because it is possible – and the answer to the problem is actually inferred from the MSDN article entitled ‘ Types supported by the Data Contract Serializer ’. The example I’m going to give is purely for illustration purposes only.  I don’t have a lot of time, so work with me! Create a new Asp.Net WCF service application, you can use Cassini as your web server (probably easier – otherwise you might have to enable...

Namespace prefixes in Microsoft Xml Document Transformation's SetAttributes and RemoveAttributes transforms

Link for the Codeplex fork I mention in this article: https://xdt.codeplex.com/SourceControl/network/forks/LordZoltan/XDTEx Get this package from Nuget using the package ID Microsoft.Web.XdtEx . Microsoft recently open-sourced the XDT library that's at the heart of the web.config transformations.  Partner this up with a new feature of Nuget 2.5 which supports the auto-importing of MSBuild .props and .targets files into a project file, and that means I could try something out with XML files in a Xamarin.Android project I'm working on at the moment. I'm building an Android app (obviously) and due to our company's needs, we want to build a vanilla app which can then be re-used for other brands within the same group.  I had the idea that I could create the whole thing as a nuget package, now that Nuget supports the 'MonoAndroid' platform. Deploying code to projects with nuget is easy - and with the partial class model in C# it's simple to deploy a core pl...