Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7744767
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T09:50:47+00:00 2026-06-01T09:50:47+00:00

I have a class that upon construction, loads it’s info from a database. The

  • 0

I have a class that upon construction, loads it’s info from a database. The info is all modifiable, and then the developer can call Save() on it to make it Save that information back to the database.

I am also creating a class that will load from the database, but won’t allow any updates to it. (a read only version.) My question is, should I make a separate class and inherit, or should I just update the existing object to take a readonly parameter in the constructor, or should I make a separate class entirely?

The existing class is already used in many places in the code.

Thanks.

Update:

Firstly, there’s a lot of great answers here. It would be hard to accept just one. Thanks everyone.

The main problems it seems are:

  • Meeting expectations based on class names and inheritance structures.
  • Preventing unnecessary duplicate code

There seems to be a big difference between Readable and ReadOnly. A Readonly class should probably not be inherited. But a Readable class suggests that it might also gain writeability at some point.

So after much thought, here’s what I’m thinking:

public class PersonTestClass
{
    public static void Test()
    {

        ModifiablePerson mp = new ModifiablePerson();
        mp.SetName("value");
        ReadOnlyPerson rop = new ReadOnlyPerson();
        rop.GetName();
        //ReadOnlyPerson ropFmp = (ReadOnlyPerson)mp;  // not allowed.
        ReadOnlyPerson ropFmp = (ReadOnlyPerson)(ReadablePerson)mp; 
          // above is allowed at compile time (bad), not at runtime (good).
        ReadablePerson rp = mp;
    }
}

public class ReadablePerson
{
    protected string name;
    public string GetName()
    {
        return name;
    }        
}
public sealed class ReadOnlyPerson : ReadablePerson
{
}
public class ModifiablePerson : ReadablePerson
{
    public void SetName(string value)
    {
        name = value;
    }
}

Unfortunately, I don’t yet know how to do this with properties (see StriplingWarrior’s answer for this done with properties), but I have a feeling it will involve the protected keyword and asymmetric property access modifiers.

Also, fortunately for me, the data that is loaded from the database does not have to be turned into reference objects, rather they are simple types. This means I don’t really have to worry about people modifying the members of the ReadOnlyPerson object.

Update 2:

Note, as StriplingWarrior has suggested, downcasting can lead to problems, but this is generally true as casting a Monkey to and Animal back down to a Dog can be bad. However, it seems that even though the casting is allowed at compile time, it is not actually allowed at runtime.

A wrapper class may also do the trick, but I like this better because it avoids the problem of having to deep copy the passed in object / allow the passed in object to be modified thus modifying the wrapper class.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T09:50:49+00:00Added an answer on June 1, 2026 at 9:50 am

    The Liskov Substitution Principle says that you shouldn’t make your read-only class inherit from your read-write class, because consuming classes would have to be aware that they can’t call the Save method on it without getting an exception.

    Making the writable class extend the readable class would make more sense to me, as long as there is nothing on the readable class that indicates its object can never be persisted. For example, I wouldn’t call the base class a ReadOnly[Whatever], because if you have a method that takes a ReadOnlyPerson as an argument, that method would be justified in assuming that it would be impossible for anything they do to that object to have any impact on the database, which is not necessarily true if the actual instance is a WriteablePerson.

    Update

    I was originally assuming that in your read-only class you only wanted to prevent people calling the Save method. Based on what I’m seeing in your answer-response to your question (which should actually be an update on your question, by the way), here’s a pattern you might want to follow:

    public abstract class ReadablePerson
    {
    
        public ReadablePerson(string name)
        {
            Name = name;
        }
    
        public string Name { get; protected set; }
    
    }
    
    public sealed class ReadOnlyPerson : ReadablePerson
    {
        public ReadOnlyPerson(string name) : base(name)
        {
        }
    }
    
    public sealed class ModifiablePerson : ReadablePerson
    {
        public ModifiablePerson(string name) : base(name)
        {
        }
        public new string Name { 
            get {return base.Name;}
            set {base.Name = value; }
        }
    }
    

    This ensures that a truly ReadOnlyPerson cannot simply be cast as a ModifiablePerson and modified. If you’re willing to trust that developers won’t try to down-cast arguments in this way, though, I prefer the interface-based approach in Steve and Olivier’s answers.

    Another option would be to make your ReadOnlyPerson just be a wrapper class for a Person object. This would necessitate more boilerplate code, but it comes in handy when you can’t change the base class.

    One last point, since you enjoyed learning about the Liskov Substitution Principle: By having the Person class be responsible for loading itself out of the database, you are breaking the Single-Responsibility Principle. Ideally, your Person class would have properties to represent the data that comprises a “Person,” and there would be a different class (maybe a PersonRepository) that’s responsible for producing a Person from the database or saving a Person to the database.

    Update 2

    Responding to your comments:

    • While you can technically answer your own question, StackOverflow is largely about getting answers from other people. That’s why it won’t let you accept your own answer until a certain grace period has passed. You are encouraged to refine your question and respond to comments and answers until someone has come up with an adequate solution to your initial question.
    • I made the ReadablePerson class abstract because it seemed like you’d only ever want to create a person that is read-only or one that is writeable. Even though both of the child classes could be considered to be a ReadablePerson, what would be the point of creating a new ReadablePerson() when you could just as easily create a new ReadOnlyPerson()? Making the class abstract requires the user to choose one of the two child classes when instantiating them.
    • A PersonRepository would sort of be like a factory, but the word “repository” indicates that you’re actually pulling the person’s information from some data source, rather than creating the person out of thin air.
    • In my mind, the Person class would just be a POCO, with no logic in it: just properties. The repository would be responsible for building the Person object. Rather than saying:

      // This is what I think you had in mind originally
      var p = new Person(personId);
      

      … and allowing the Person object to go to the database to populate its various properties, you would say:

      // This is a better separation of concerns
      var p = _personRepository.GetById(personId);
      

      The PersonRepository would then get the appropriate information out of the database and construct the Person with that data.

      If you wanted to call a method that has no reason to change the person, you could protect that person from changes by converting it to a Readonly wrapper (following the pattern that the .NET libraries follow with the ReadonlyCollection<T> class). On the other hand, methods that require a writeable object could be given the Person directly:

      var person = _personRepository.GetById(personId);
      // Prevent GetVoteCount from changing any of the person's information
      int currentVoteCount = GetVoteCount(person.AsReadOnly()); 
      // This is allowed to modify the person. If it does, save the changes.
      if(UpdatePersonDataFromLdap(person))
      {
           _personRepository.Save(person);
      }
      
    • The benefit of using interfaces is that you’re not forcing a specific class hierarchy. This will give you better flexibility in the future. For example, let’s say that for the moment you write your methods like this:

      GetVoteCount(ReadablePerson p);
      UpdatePersonDataFromLdap(ReadWritePerson p);
      

      … but then in two years you decide to change to the wrapper implementation. Suddenly ReadOnlyPerson is no longer a ReadablePerson, because it’s a wrapper class instead of an extension of a base class. Do you change ReadablePerson to ReadOnlyPerson in all your method signatures?

      Or say you decide to simplify things and just consolidate all your classes into a single Person class: now you have to change all your methods to just take Person objects. On the other hand, if you had programmed to interfaces:

      GetVoteCount(IReadablePerson p);
      UpdatePersonDataFromLdap(IReadWritePerson p);
      

      … then these methods don’t care what your object hierarchy looks like, as long as the objects you give them implement the interfaces they ask for. You can change your implementation hierarchy at any time without having to change these methods at all.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

in AS3, I have an external class ImageLoader, that loads an image upon request.
I have a presenter class that will spawn a new presenter and view upon
I have a windows form application that uses a Shared class to house all
Basically I have a class A which creates an array upon construction. class A
I have class that represents users. Users are divided into two groups with different
I have class A such that: class A { static int i; A(); f1();
I have a class that implements the IDisposable interface. I am using a webclient
I have a class that is marked with DataContract attributes and I would like
I have a class that requires a specific method to be called before being
I have a class that maps incoming messages to matching readers based on the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.