views:

330

answers:

5

Can I write a unit test that make sure that a readonly class I write (a class which has no setters) remains readonly in the future? I do not want that anyone to add a setter property in my classes.

Basically, how do I check if a class is has no setters in C#?

+5  A: 

Note: asker originally posed the question "How do I determine if a class is a Value Type?" and later changed it.

bool isValueType = object.GetType().IsValueType

or

bool isValueType = typeof(YourClass).IsValueType

MSDN: http://msdn.microsoft.com/en-us/library/system.type.isvaluetype.aspx

Rex M
I am referring to value type pattern.. I want to test if a class has no setters... I do not want to know if it is a struct or other language specific value type such as int...
StackUnderflow
see my other answer
Rex M
+3  A: 

This should come up zero:

var setterCount =  
    (from s in typeof(IDataCollector).GetProperties(
        BindingFlags.Public | BindingFlags.Instance)
    where s.CanWrite == true
    select s)
    .Count();
ctacke
A: 
    Type type = typeof(YourClass);
    PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance);
    bool passesTest = true;
    foreach (PropertyInfo property in properties)
    {
        passesTest = passesTest && property.CanWrite;
    }
Rex M
A: 

How about just marking all the fields readonly?

Andrew Peters
I assume the poster was concerned about derived classes adding mutable fields.
mquander
Why would you assume that?
Andrew Peters
Because he expressed his concern that the class "remains readonly in the future." It seems to me that the most plausible scenario in which some other programmer might make the class mutable "accidentally" would be to derive from it and add mutable fields.
mquander
See Princess' answer.
Andrew Peters
+2  A: 

I think the key phrase here is "I do not want that anyone to add a setter property in my classes."

In general, if you want to write an immutable class, you should mark your class as sealed and mark all fields as readonly.


Of course, if you expect people to inherit from your class, you have to consider the following:

  • There's nothing preventing a person from inheriting from adding whatever properties they want to your class. You can't enforce that constraint on inheritors, except by convention.

  • You can do a runtime check using reflection to see if inheritors have added any fields, however I wouldn't recommend it since it violates some of the elementary principles of encapsulation.

  • You have to check for more than just setters in your class. Its wholly possible for a person to write a method like setSomething (a Java-style setter), or writing methods with side-effects that mutate internal values. There's no efficient way to check if your inheritors haven't used similar trickery to sneak mutability in your classes.

There's really nothing you can do to keep your class readonly if you allow people to inherit your class.

Juliet