views:

112

answers:

5

i wanna know if there is any pattern that can overcome this problem: i have a set of properties that needed to be public to serveral classes and to other classes they should be only readonly, the classes must be public.

i do not wanna use reflection or any other bad performance makers

i know i can make them RO and implement logic inside class but i don't think its good

any help???

+2  A: 

Two options:

  1. Make the property internal (not the class) and group the classes into different assemblies.
  2. Use reflection magic.

Sadly, there are no friend classes in C#.

Johannes Rudolph
+8  A: 

Inside the current assembly, you can make it internal.

Outside the current assembly, the best you can do is make it available to specific assemblies, via [InternalsVisibleTo].

.NET does not offer more granular "friend" access.

Marc Gravell
I think this should be considered an anti-pattern.
Johannes Rudolph
I agree with Johannes. Actually, I think you have a design problem if you want to have different member accessibility for different callers. .NET lackes finer granulatet friends for good.
Maximilian Mayerl
Very valid points; indeed, I generally only use [InternalsVisibleTo] for unit tests.
Marc Gravell
@Johannes -- I disagree. I can think of several good reasons to do this, though I'd typically restrict use of InternalsVisibleTo only to test assemblies. It allows the use of factories (in the same assembly) to access property settors while retaining the readonly nature of the a property, it's almost required when doing integration work against the DB of an application to add functionality safely by rigidly defining the types of interactions that can take place outside the data layer within designer generated classes.
tvanfosson
We do many things for unit tests we wouldn't do for production code, do we? (think of all the reflection etc.) I consider [InternalsVisibleTo] to be fine for unit tests. That why I didn't downvote.
Johannes Rudolph
+6  A: 
class Person : IReadOnlyPerson {
    public string Name { get; set; }
}

public interface IReadOnlyPerson {
    string Name { get; }
}

To those classes that should do r/o access - use IReadOlyPerson

That's a good one.
devoured elysium
A: 

You could try declaring your setters as protected in your base class. Any class that derives it will be able to set it. But any class using the derived class will only see a read-only property.

public class ClassBase
{
    public int MyProperty
    {
        get;
        protected set;
    }
}

public sealed class ClassDerived : ClassBase
{
    public ClassDerived()
    {
        MyProperty = 4; // will set
    }
}

public class ClassUsingDerived
{
    public ClassUsingDerived()
    {
        ClassDerived drv = new ClassDerived();
        drv.MyProperty = 5; // will fail
    }
}

That is if i understand the question correctly :)

Sergey
That only works if the class in question is a derivative. What happens when the consumer is *not* a derivative? I think that's his real problem.
Mike Hofer
A: 

InternalsVisibleToAttribute?

Alex Reitbort