I'd like to have the following setup:
class Descriptor
{
public string Name { get; private set; }
public IList<Parameter> Parameters { get; private set; } // Set to ReadOnlyCollection
private Descrtiptor() { }
public Descriptor GetByName(string Name) { // Magic here, caching, loading, parsing, etc. }
}
class Parameter
{
public string Name { get; private set; }
public string Valuie { get; private set; }
}
The whole structure will be read-only once loaded from an XML file. I'd like to make it so, that only the Descriptor class can instantiate a Parameter.
One way to do this would be to make an IParameter
interface and then make Parameter
class private in the Descriptor class, but in real-world usage the Parameter will have several properties, and I'd like to avoid redefining them twice.
Is this somehow possible?
You could use a constructor marked Internal.
That way it's public to classes in the assembly, and private to classes outside of it.
LBushkin has the right idea. If you want to avoid having to retype all the properties just right-click the name of the class and choose "Refactor" > "Extract Interface", that should give you an interface that contains all those properties. (This works in VS 2008, I don't know about earlier versions.)
C# generally takes the approach that instead of avoiding redundant code, VS will just help you write it faster.
If you want only the Descriptor class to instantiate a Parameter, then you can make the Descriptor class a nested class of Parameter. (NOT the other way around) This is counterintuitive as the container or parent class is the nested class.
Mark the class to be "protected" from instantiation (Parameter) with the
StrongNameIdentityPermission
attribute and theSecurityAction.LinkDemand
option:You will need to provide the appropriate public key. Because you are demanding a link-time (JIT-time, in fact) check on the
Parameter
class, this means that it can only be used from an assembly that is signed with a strong name that uses the private key matching the public key that you supply in the attribute constructor above. Of course, you will need to put theDescriptor
class in a separate assembly and give it a strong name accordingly.I have used this technique in a couple of applications and it worked very well.
Hope this helps.
Make it a private nested class that implements a particular interface. Then, only the outer class can instantiate it, but anyone can consume it (through the interface). Example:
If you really must avoid the interface, you can create a public abstract class that has all of the properties but declares a protected constructor. You can then create a private nested class that inherits from the public abstract that can only be created by the outer class and return instances of it as the base type. Example:
There is another way: check the call stack for the calling type.