Omer van Kloeten's .NET Zen

Programming is life, the rest is mere details

News

Omer van Kloeten's Facebook profile

Omer has been professionally developing applications over the past 8 years, both at the IDF’s IT corps and later at the Sela Technology Center, but has had the programming bug ever since he can remember himself.
As a senior developer at NuConomy, a leading web analytics and advertising startup, he leads a wide range of technologies for its flagship products.

Get Firefox


powered by Dapper 

.NET Resources

Articles :: CodeDom

Articles :: nGineer

Culture

Projects

WPF's Use of Partial Classes' Access Modifiers

While writing a reusable component for a client, I placed it in a different assembly and began to change all of the non-public classes' access modifiers to internal. Building the project, I received the following error:

error CS0262: Partial declarations of 'ClassName' have conflicting accessibility modifiers.

The two conflicting source files were my original ClassName.xaml.cs file and the automatically generated ClassName.g.cs file. It appeared that the ClassName.g.cs stated that my class was still public. Here are my types:

MyWindow.cs:

internal partial class MyWindow : Window

MyWindow.g.cs:

public partial class MyWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector

After a bit of digging, I found the culprit. Apparently, when you have a non-public modifier, you have to qualify your element with the x:ClassModifier attribute. In my case, the code looked like this:

<Window x:Class="MyNamepsace.MyWindow" x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

All works and all is well in the world... Well, not everything. You see, this is both ugly and easily avoidable.

Why is this ugly? The x:ClassModifier attribute clearly states that the string passed to it:

[...] varies, depending on the code-behind programming language being used.

This makes your XAML file's correctness bound to the language the code-behind is written in, rather than be language-neutral and CLR-centric.

Another assumption made by WPF's design team was that the default value is public, which means every type is added to the list of publicly visible types in your assembly by default. If you write a client application, this may not be of any concern to you, but if you write reusable components, this is a highly important design decision. On the other hand, this might just be me nitpicking.

How could this be avoided? As you may well know, when defining a partial class, the definition is collected from every part, glued together, and only then are default behaviors appended and the code is compiled. This means that if you fail to write an access modifier in one file and only write it in another, there will be an access modifier, but on the other hand, writing two conflicting modifiers will cause a compiler error.

This means that the only thing needed to be done to avoid the entire need for the x:ClassModifier attribute was to emit generated code with no access modifier and have the code-behind implicitly take control of it.

Final words: This can also be found in base class references, where all partial classes are marked as deriving from the same base type, as you can see in the examples above. Then again, this may just be a safeguard against people messing with their base classes... who knows.
I hope this would go away in the next version of the designer. Is anyone listening?

Comments

Marc said:

This is actually strange because if I add a button to a WPF form in the designed in vc# 2008 express and look at the generated code, it defines it as internal, not public as you say.

Actually I searched a way to change that to some other value as well so I started searching - and found your post. I still don't know how to specify the access modifier of a control I add to an WPF form.

# November 23, 2007 2:54 PM

Omer van Kloeten said:

Marc,

This post actually refers to the access modifier of the main class in the file.

If you want to do what you're looking for, use x:FieldModifier instead.

And yes, I can't understand why they'd use 'internal' as the default for that either...

# November 23, 2007 3:07 PM

DevTopics | Best C# Blogs said:

Pingback from  DevTopics | Best C# Blogs

# December 11, 2007 9:08 AM

布衣 said:

在IT行业,中文的资料永远都比英文的慢几个月,而且原创性的也少得可怜,有空时,不妨去这些英文技术BLOG溜达溜达,也许会有意外的惊喜。 好的C#博客应该符合这些条件: 有用的新闻、信息、技巧和代码例子 定期更新 原创内容,不是广告文章盗用别人的文章 良好的组织,包含分类和tags 健康的讨论和读者评论 有一定的个人见解,最好还有点幽默感,但又不是自己在嗐吹牛

# September 3, 2008 5:51 AM

Subindev said:

This is a really a useful information.

Thanks a lot:-)

# January 5, 2009 12:58 AM

aza77 said:

Good to know .. thanks ;)

# May 9, 2009 1:54 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)