0

I basically want to do something like this

public string Password
{
  set { password = value; }
}

internal string Password
{
  get { return password; }
}

But without having to call my second function something else (the code above will not compile as I used the name Password twice). I could have setPassword and getPassword, but that seems a bit, well, rubbish :(

My scenario is that I've a separate assembly (class library) that contains the core business logic. I would not want any projects that use the class library to be able to view the password once set.

Lennart
  • 9,657
  • 16
  • 68
  • 84
friartuck
  • 2,954
  • 4
  • 33
  • 67
  • You can apply access modifiers to the get and set. – cadrell0 Jan 16 '13 at 18:24
  • Yeah I figured it out in the end. It was a similar error in a separate project that linked to this project (core logic), that referenced an internal part of a class that was throwing an error. I was thrown by the compiler error, thinking what I had done was illegal. Any this post should still be useful to people Thanks all the same :) – friartuck Jan 17 '13 at 14:31

6 Answers6

8

It's as simple as:

public string Password { internal get; set; }

It's worth noting that this is an unusual thing to see, and would violate many people's expectations about properties. While this is possible, it would be preferable to have a public method SetPassword and either an internal field, or an internal GetPassword method. People simply don't expect to come across a property they can set but not get (even though the reverse is common). This is probably one of the few valid use cases for it, but just to follow the "least surprise" methodology, consider using methods instead.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 1
    Very good point on user expectations. I would recommend a `SetPassword(...)` method versus a write-only property. – Erik Jan 16 '13 at 18:46
  • Good explanation. I was wondering, is it possible to throw a compile time error using meta information if people try assigning to the field? – friartuck Jan 17 '13 at 14:33
  • @Prof That's the advantage of using auto-implemented properties; there is no way to assign to the field at compile time. – Servy Jan 17 '13 at 14:38
2

A getting and setting can have different access modifiers:

public string Password {
    internal get { return password; }
    set { password = value; }
}
shf301
  • 31,086
  • 2
  • 52
  • 86
2

I believe you can just write this:

private string password;
public string Password 
{ 
    internal get 
    { 
       return password; 
    }
    set
    {
        password = value;
    }
}
Kevin DiTraglia
  • 25,746
  • 19
  • 92
  • 138
2
string _password;   
public string Password
{
     internal get { return _password; }
     set { _password=value; }
}
Brian
  • 5,069
  • 7
  • 37
  • 47
Dan Hunex
  • 5,172
  • 2
  • 27
  • 38
2

As simple as this:

public String Password
{
    internal get { return m_Password; }
    set { m_Password = value; }
}

Here is another solution:

public string Password
{
    set { m_Password = value; }
}

internal String InternalPassword
{
    get { return m_Password; }
}
Tommaso Belluzzo
  • 23,232
  • 8
  • 74
  • 98
1

If you are trying to be security-conscious (as it would seem you are), then I suggest SecureString in the System.Security namespace. It keeps the contents of the string encrypted in memory.

You could still have a property like this:

SecureString password;

public string Password
{
  internal get { return password.ConvertToInsecureString(); }
  set { password = value.ConvertToSecureString();
}

You'll need this extension method class:

using System.Runtime.InteropServices; // For Marshal static class
using System.Security;                // For SecureString class

public static class SecureStringExtender
{
  public static SecureString ConvertToSecureString(this string text)
  {
    if (text == null)
      throw new ArgumentNullException("text");

    var secureString = new SecureString();

    foreach(var c in text)
      secureString.AppendChar(c);

    secureString.MakeReadOnly();
    return secureString;
  }

  public static string ConvertToInsecureString(this SecureString secureString)
  {
    if (secureString == null)
      throw new ArgumentNullException("secureString");

    IntPtr unmanagedString = IntPtr.Zero;

    try
    {
      unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
      return Marshal.PtrToStringUni(unmanagedString);
    }
    finally
    {
      // Zero out the sensitive text in memory for security purposes.
      Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
    }
  }
}
Erik
  • 12,730
  • 5
  • 36
  • 42