2

This question is similar to this one: Restrict method access to a specific class in C++

However, my question is for C#.

To reiterate: I have two classes, say Foo and Bar which are tightly coupled. Foo exposes a method that I only ever want Bar to have access to.

I kinda have an idea of what I want but no idea how to actually do it, or know if a simpler way exists. It would involve using some kind of attribute that relies on using (new StackFrame(1)).GetMethod().DeclaringType to deny access. Usage would look something like this:

public class Foo {

    [RestrictedUsage(Allow=typeof(Bar))]
    public int SomeMethod() 
    {
        // do something
    }

}

There are probably relevant details I'm missing for the question (I'm new here) - I'll be sure to update it as I go.

UPDATE: I should mention that Foo wraps an existing UIElement who's behavior I am trying to modify. Since the class is sealed, it's difficult to modify it normally. Bar is the class that transforms the values into the correct values. Bar is non-UI and is used other places in my application. Foo doesn't know how to transform the value (it's complex - thats what Bar is for) and that's why I can't just wrap the base method.

Jon Skeet gave the answer I was expecting - change the layout of the classes (all thanks be to him so far) but I don't think either answer is applicable (good answers just not relevant).

I've already made mistakes in the code, referencing the wrong property...

Community
  • 1
  • 1

2 Answers2

6

Two options:

  • Put Foo and Bar in a separate assembly, and make Foo's method internal
  • Make Bar a nested class within Foo, and make the method private

The latter is usually the more practical option, if it's reasonable to make Bar a nested class.

If neither of these work, I think you're best off just using an internal method and documenting it - how much do you mistrust the rest of the code in the assembly?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I do mistrust the code, because I am not the only one using it. Since Foo is also a UIElement it is naturally referred too elsewhere (ruling out separate assembly). – Anthony Truskinger Feb 16 '10 at 22:30
  • Not being the only one using it isn't necessarily a reason to mistrust the code. Do your colleagues regularly ignore documented "do not use this" type warnings? Also, just because Foo is referenced elsewhere doesn't mean it can't be in its own assembly... – Jon Skeet Feb 16 '10 at 23:13
  • I ended up nesting the class. I restructured some other parts a little and the new result is great. Thanks! – Anthony Truskinger Feb 19 '10 at 01:57
0

Normally i'd suggest something like the following:

public abstract class Foo:UIElement{
    //...
}

public class Bar:UIElement{
    //...
    private class FooImpl:Foo
    {
        public int SomeMethod() 
        {
            // do something
        }
    }
} 

But if we're dealing with UIElements, then we're probably also dealing with XAML? A class structure like this would make it hard to instantiate a Foo/FooImpl in XAML, since you'd probably need to use the factory pattern...

Rob Fonseca-Ensor
  • 15,510
  • 44
  • 57