If I have constants in a class that are related to each other lets say strings used to write/read Xml file for MyClass, should I wrap them in a nested class Xml inside MyClass? Or just define them without wrapping in MyClass? If it is a good idea to wrap them than what if only part of those constants should be accessible to the outside world for example only the Xml.Name and the rest are Xml attributes that MyClass will use for recreating objects, what would I set the protection level of my nested class to?
I see a nested-class as an object that only makes sense within the context of another object; and whose logic requires properties of this other object. Given that, I've never designed a nested-class that I didn't later refactor away. And I see the perceived need for a public nested-class as a red-flag for a troubled design.
Regardless, your question has me considering whether they are potentially useful. So even though I won't be using this sort of design it may work for you.
I did want to mention that const should only be used for things that never change. Like the hours in a day or the speed of light. I can't exactly tell from your question but something like Xml.Name appears to be variable. I suggest using readonly for these properties. Possibly, static readonly if they're consistent through all instances. This will steer you clear of the many pitfalls of const.
The following is a class I mocked up to demonstrate what I'd recommend for your design:
public class MyClass
{
public string Title { get; set; }
Xml _xml;
public Xml MyXml
{
get { return _xml; }
set { _xml = value; }
}
public MyClass(string xmlName, object xmlAttributes)
{
_xml = new Xml(xmlName, xmlAttributes);
}
public class Xml
{
private readonly string _name;
public string Name
{
get { return _name; }
}
private readonly object _attributes;
internal object Attributes
{
get { return _attributes; }
}
public Xml(string name, object attributes)
{
_name = name;
_attributes = attributes;
}
}
}
I see no need to move the constants to a nested class.
Accessibility:
Make constants only needed by MyClass *private*.
Make constants only needed by classes which are in same assembly as MyClass *internal*.
Make constants only needed by subclasses of MyClass and by MyClass itself protected.
Make constants only needed by classes which are in same assembly as MyClass or by subclasses of MyClass and by MyClass itself internal protected.
Make constants also needed by classes in other assemblies than MyClass's one public.
Naming:
If you have many constants in one class use good prefixes to categories them. So the reader can find faster the right one.
Related
[Edit] What I wanted to ask was just putting a class name with this, so it wasn't about referencing an outer class member. Sorry for my inappropriate example!
[Edit2] Someone reported this as a duplicate BUT NOT! As I said earlier, I just wanted to know if it's possible to reference MyClass.this and this interchangeably like in Java. This wasn't a practical question at all but just for learning C# language itself. I don't mind removing this if people really think it's a duplicate so let me know.
In Java, you can use this with class names like this:
class OuterClass {
int outerMember = 1;
class InnerClass {
int innerMember = 2;
public void printOuterMember() {
System.out.println(OuterClass.this.outerMember);
System.out.println(outerMember);
}
public void printInnerMember() {
System.out.println(InnerClass.this.innerMember);
System.out.println(this.innerMember);
System.out.println(innerMember);
}
}
}
Sometimes class names are not needed, but sometimes helpful.
So I tried the same thing in C# but it seems it's impossible. Am I right?
C# does not support this, in Java the nested class captures the parent object reference. C# nested classes are more like static nested classes in Java. If you want access to the parent class you will need to pass a reference to it in the nested class constructor.
Nested classes will have access to private fields of the parent class if they have a reference to it, so you can achieve similar results, just the access to the parent class instance is not automatic as it is in Java. So this code works
class Owner
{
private int field;
class Nested
{
public Nested(Owner owner) { this.owner = owner; }
Owner owner;
public int D()
{
return owner.field;
}
}
}
Is there any use of declaring a static class as private.Here is the code below:
static class DerivedClass
{
private static string GetVal()
{
return "Hello";
}
}
The sample code you provided actually illustrates an internal class, not a private class. This is perfectly fine and is done all the time. It means the methods of the class are available from other classes within the same module, but not externally.
If you mean declaring private members of static classes, sure there is.
static class DerivedClass
{
public static string GetVal()
{
return GetValInternal();
}
private static string GetValInternal()
{
return "Hello";
}
}
If you mean declaring a private static nested classes (because only nested classes can be private, according to the documentation), then you can do it, but there's probably no reason to do it.
class SomeClass
{
private static class DerivedClass
{
public static string GetVal()
{
return "Hello";
}
}
}
Is equivalent to
class SomeClass
{
private static string GetVal()
{
return "Hello";
}
}
By default classes with no access modifiers like in your example are internal, not private. See this reference: http://msdn.microsoft.com/en-us/library/ms173121.aspx. This means that you can access this class from anywhere inside the library/project. This makes sense because it allows you to use the class internally without necessarily exposing it to the outside world.
Explicitly declaring it as private however makes sense in some rare cases only in my opinion. I have used it before for nested classes simply to group certain things together and make my code prettier/more readable. However I find that if I am creating nested classes it usually means that I need to redesign my code and pull some of it into separate files and separate classes. Rather try to stick to one class per file.
I'm trying to create a class (in C#) that serves as an environment for my application.
I'm trying to make the class dynamic, and send it as a parameter to entities in my application. The problem is, that I want to be able to change the properties of this environment class (public setters), but at the same time I want the classes that receive the environment to be unable to use these setters.
I can't seem to find a good way to phrase my question (which I figure is a part of the reason I can't find anything like this on Google or msdn), but to put shortly, I want to create a class with setters that are public only for some of my objects and not for all.
I'm currently amusing the following idea:
Avoiding the public setters all together, and expose the private fields using event registration.
The class will register to events in a new third object (sent as a parameter to the constructor). The methods that will be registered by the environment are not much more then setters, and so triggering these events will "allow access" to the private fields.
I'd love some ideas (seeing as I feel that mine isn't all that great), or better yet some patterns I could make use of.
Thanks in advance
Isn't "internal" sufficient for what you need?
And you could move the setters into an interface as explicit implementation. Then they are hidden from the public interface and only accessible if you cast to the interface.
And if you want to make really sure that nobody else can call it you can add some parameter to these functions where you expect a certain token object which you only give to trusted classes.
void SetX(int value, object token)
{
if(token!=correctToken)
throw new ArgumentException("wrong token");
x=value;
}
You could create a proxy, and send that proxy to your entity classes.
class MyClass
{
public int MyProperty { get; set; }
}
class MyProxyClass
{
public MyProxyClass(MyClass myClass)
{
_myClass = myClass;
}
private MyClass _myClass;
public int MyProperty
{
get { return _myClass.MyProperty; }
}
}
You could try using Friend assemblies. That will allow only the assemblies you specify to have access to your privates (snicker).
Maybe i understood something not quite well, but i think Jon had a quite similar problem which he described here. Maybe this can help you.
How about
class Callee
{
public void SetX(TypeOfCaller caller, int value)
{
}
}
class TypeOfCaller
{
public void Do()
{
Callee instance;
//..
instance.SetX(this, 5);
}
}
Doing so; you can also use Visual Studio' Find References feature! In case you want multiple types of caller; you can either opt for class hierarchy or can simply have required overloads
Why not return clones of your protected objects instead of the actual objects? Solves the problem without adding any more complexity.
public class MyService
{
private List<MyObject> _protectedObjects = new List<MyObject>();
public MyObject GetItem(int id)
{
return (MyObject)_protectedObjects.First(i => i.Id == id).Clone();
}
}
public class MyObject : ICloneable
{
//[...]
public object Clone()
{
return MemberwiseClone();
}
}
Suppose I have Class A with some properties and Attributes, and Class B with the same, how can I merge these 2 class Properties and properties Attributes into 1 class at runtime, or better is how can I add these 2 classes into a a third class as properties of this new class with their Fields, Properties, Methods, etc... at Runtime ?
Using reflection or the News .NET 4.0 Dynamic or expando Object
Edit: Damn I am sorry to all for not being clear, what I want is to create a dynamic ViewModel for MVC, where other classes are in some other assemblies, and I want them to be part of the model with their Datavalidation attributes. and I don't know how many or what exactly these classes are gonna be, so I want to iterate through assemblies and choose them then add them to the main View Model.
You can't change a type at runtime. Expando might be an option, but I am not clear how you want to interact with this object, as you would seem to be limited to reflection, and expando is not a huge friend of reflection.
It might help to clarify your requirement here, but IMO you might do better to consider loading (at runtime) a property-bag based on reflection from the two inputs; something like a Dictionary<string,object> which would let you map named keys to values.
One other thing that might be what you are after here is partial classes, but this is a single type spread over multiple source files:
partial class Foo {
private string bar;
}
partial class Foo {
public string Bar { get {return bar;} set {bar = value;} }
}
A final option here is TypeBuilder, but that is massive overkill in most scenarios.
Assuming you don't have access to the code for either of the classes (otherwise you could just merge the code), you can create a wrapper that aggregates the two classes with the combined interfaces:
public class AandB
{
private ClassA _instanceA = new ClassA();
private ClassB _instanceB = new ClassB();
public bool PropertyA
{
get
{
return _instanceA.PropertyA;
}
set
{
_instanceA.PropertyA = value;
}
}
public bool PropertyB
{
get
{
return _instanceB.PropertyB;
}
set
{
_instanceB.PropertyB = value;
}
}
}
I've got a base class from an outside library that I can't modify - here's the relevant piece:
public class BaseClass
{
List<string> _values;
public Values { get { return _values; } }
}
I am inheriting the BaseClass, and I want to set _values to a class that inherits from List(T) in the constructor:
public InheritingClass : BaseClass
{
public InheritingClass():base()
{
//set base._values = new InhertingList<string>(); ?
}
}
What's the best way to set base._values there? Is there a way to find what private variable is fetched by Values and set that in case the private variable is renamed in the future?
There are other ways I can accomplish what I need to do, but if I could do the following, it would be quicker by far than any ways of achieving my goal without setting the private property value.
Keeping it private, by definition, is meant to prevent this exact scenario.
The best option would be to implement a protected setter:
public class BaseClass
{
public Values {
get { return _values; }
protected set { _values = value; }
}
}
This way, your InheritingClass has access to the setter, and can do:
this.Values = new InhertingList<string>();
But since you can't change the base class, it is, technically, possible to do this via reflection (in a full trust scenario). I don't recommend this approach, though:
FieldInfo field = typeof(BaseClass).GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic );
field.SetValue(this, this.Values = new InhertingList<string>() );
The danger of doing what you are attempting, btw, is that you're going to change the implementation defined by the BaseClass to something that you're providing. It's very easy to introduce subtle bugs, since you're (purposefully) "breaking" the implementation details in the base class.
I'd try to rethink your algorithm, and see if there's another way around this issue.
If you really need to set the value, you can use reflection. But that's no good coding style and may be slow.
Edit:
It might be possible to disassemble your BaseClass and change its implementation. Bun then you might have to disassemble the whole library.
Perhaps you can provide some more details on your problem?
Usually, when you don't have a property with an accessible setter provided for a field, it means that you should not modify that field from anywhere but the BaseClass - if the creator of the BaseClass class would have wanted you to be able to modify that field, he'd have exposed a property with a protected setter or something like that. So generally it's not recommended to hack it.
You could certainly do it by reflection though, providing you know the name of the private field - I don't think it is possible to extract the body of the property.
As for the other answers: he wrote "I've got a base class from an outside library that I can't modify".
You can't set the private property. You will either have to inherit from another base class or create your own base class that provides the behaviour.
Of course, depending on the level of trust your application is running under, you may be able to set the private variable via reflection but that would really be a hack to get around what is actual a problem in the design.
No, there is no way to do what you're looking for. Private variables are meant to be private - namely, they can't be seen or altered by any code.
Normally, when fields don't have mutator methods, you'd use the constructor of the class to instantiate the object (and it's relevant fields).
BaseClass base = new BaseClass(List<string> yourList);
You could always utilize the "new" keyword, but the inherited method would be ignored if the class is cast back to its base object
public InheritingClass : BaseClass
{
public InheritingClass()
{
Values = new InhertingList<string>(); ?
}
public new List<string> Values { get; private set; }
}
To access private fields you can use Reflection, but since the field is private I'm not certain how the inheriting class would benefit from changing a private field type.
public InheritingClass : BaseClass
{
private static FieldInfo _valueField = typeof(BaseClass).GetField("_values", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
public InheritingClass()
{
_valueField.SetValue(this, new InhertingList<string>());
}
}
http://msdn.microsoft.com/en-us/library/6z33zd7h(v=vs.110).aspx