tags:

views:

109

answers:

3

Dear ladies and sirs.

Observe the following code:

[AttributeUsage(AttributeTargets.All)]
public class XAttribute : Attribute
{
}

public struct A
{
  [X]
  public static extern int XX { get; }
}

This does not compile. The error message says

The modifier 'extern' is not valid for this item

But, the following code compiles OK:

[AttributeUsage(AttributeTargets.All)]
public class XAttribute : Attribute
{
}

public struct A
{
  [X]
  public static extern int GetXX();
}

Why ???

EDIT

Guys, guys. I would not have asked had I not had a real application for this. I understand, that purely academic interest to understand why some things are defined the way they are is not something that motivates some of us, so here is the down to earth motivation. I have a PostSharp attribute, that injects a certain logic into the attributed extern property. Specifically, the real code looks like so:

[LoggerAccessProperty]
private static extern ILog Logger { get; }

Where PostSharp processes the LoggerAccessProperty aspect and injects the actual getter method, which surfaces the private static compiler generated ILog instance. This is part of our in-house extension of the Log4PostSharp package. At the time, we have published the extended version of Log4PostSharp at the PostSharp google code site and this attribute is my recent addition, yet unpublished.

EDIT2

Note, that the following code compiles just fine:

[AttributeUsage(AttributeTargets.All)]
public class XAttribute : Attribute
{
}

public class A
{
  [X]
  public static extern int XX { get; }
}

The difference is that A is a class here, not struct.

EDIT3

I am using .NET 4.

+1  A: 

extern properties are not allowed in structs.

Yuriy Faktorovich
A reference to the language spec, please.
mark
@mark: I tried actually, couldn't find it. I assume it was because of stricter Struct rules, but didn't put it as part of the answer because wasn't sure.
Yuriy Faktorovich
Well, then this is not much of an answer. I already know that one cannot have extern properties in a struct, unlike classes - I have found it out the hard way. The question why remains unanswered...
mark
+1  A: 

The extern modifier is used to declare a method that is implemented externally.

The above is the first line of documentation for the extern keyword. (With emphasis added). Given that it only applies to methods (not properties), one has to ask: What are you even trying to do? The fact that it's a struct rather than a class, and the presence of an attribute in your code examples both seem to be red herrings.

Damien_The_Unbeliever
extern properties are fine in classes.
Yuriy Faktorovich
@Yuriy Faktorovich: please provide some working sample code. I doubt the CLR implements it in any form.
leppie
Of course, the question is still 'why'. Properties ultimately are just methods, compiled as get_XXX and set_XXX. So why not allow them to be `extern`s?
Kevin Brock
@leppie Not a clue what it would be used for, but it does compile. http://msdn.microsoft.com/en-us/library/aa664450(VS.71).aspx.
Yuriy Faktorovich
@Yuriy Faktorovich: It compiles, but does it even run? I highly expect a runtime/type load exception.
leppie
I have edited the question - added the motivation.
mark
A: 

Because an external method declaration provides no actual implementation, there is no method body; the method declaration simply ends with a semicolon and there are no braces ({ }) following the signature.

So if you changed your code to:

[LoggerAccessProperty]
private static extern ILog Logger();

It should work fine in your struct.

Reference Link

Tony Abrams
However, the extern property compiles just fine for classes. Your reply neither explains nor indicates any difference between the struct and class with respect to extern properties, while there is and I want to known why.
mark
Your question above shows two stucts (I see no mention of struct vs class). There is no difference between the handling of externs in structs vs classes. You simply cannot have an external property, because an external has no method body. A property (in any form) has a method body (IE: {get; set;} or either one) making it invalid to be used with extern. As for the compiling part, that's pretty odd.
Tony Abrams
Also it might be good to know which version of the framework you are using. It would help with finding the right documentation. Just saying.
Tony Abrams
Updated the question. Added a code snippet, demonstrating that a class can have extern properties and this is as opposed to structs, which cannot and this difference is the essence of my question.
mark