views:

92

answers:

1

I'm creating a class that will house election results. I have a results class that has a static method that will parse a file and return a results class with the results from the file.

I want to make sure that only the static method can modify the results, so i've been using the internal modifier (Precinct.InternalCandidates) (The prevents instances of my class outside of the dll from accessing the methods, right?).

Anyway, I need to expose the candidates as a read only list to the instantiated version of my class, but I'll obviously need to be able to add candidates during the population process. So, I've created another parameter in the Precinct Class called Precinct.Candidates that exposes a read only version of InternalCandidates

Here's how I'd envision it to work:

Results r = Results.ParseResultsFile("PathToFile.txt");
r.Candidates.Add(new Candidate) // Should error here
Console.WriteLine(r.Candidates[0].Name) // Should work

Here's what I have for my class stubs:

public class Results {
  private List<Precinct> precincts = new List<Precinct>();
   public ReadOnlyCollection<Precinct> Precincts {
      get { return this.precincts.AsReadOnly(); }
  }

  public Results() {}

  public static Results ParseResultsFile(string filePath) { ... }
}

public class Precinct {
  internal List<Contest> InternalContests { get; set; }
  public ReadOnlyCollection<Contest> Contests {
    get { return this.InternalContests.AsReadOnly(); }
  }
  public Precinct {
    this.InternalContests = new List<Contest>();
  }
}

Is there a better way to accomplish this?

+2  A: 

I'm afraid I have a little bit of bad news Rob... using Reflection, one can completely circumvent access modifiers. They help to protect a team from themselves, but are not suited to providing security.

You will need to ensure the physical security of the code and ensure that nobody can load your DLL into an app domain of their own creation.

UPDATE:

I stand corrected by myself. You can set an attribute that prevents reflection UNLESS THE CALLER HAS FULL TRUST (update from Leppie). See how.

You can prevent callers without full trust from accessing your private/internal methods and fields but a full trust caller cannot be prevented from using reflection.

Eric J.
FullTrust overrides everything, so that attribute wont help.
leppie
In addition, that attribute has to be applied to the *calling* program, not the *callee* assembly. So Rob could only secure himself that way if his attackers were polite enough to deny themselves reflection permission **grin**. And the attribute will be ignored if/when he moves to .NET 4.
itowlson
okay... i'm not really worried about someone malicious doing it. In fact, if they really want to mess with the data, they'd just change the text file. This is just so my team (you read: me) wont accidentally do something stupid like Precinct.Candidates.Add().I'm just wondering if having both an internal and public property that point to the same thing is the best way to accomplish what i'm trying to do. I'd love to not have to have InternalContests, but have Contests.Add only be Internal. Maybe I need to not use List<> and derive my own?
Rob