In the following scenario:
public class outerclass
{
public innerClass Ic
{get;set}
public class innerClass
{
}
}
Do you need to instantiate the inner class property before assigning values to it, like this?
public class outerclass
{
public outerclass()
{
this.Ic = new innerClass();
}
public innerClass Ic
{get;set}
public class innerClass
{
}
}
It doesn't matter in what scope class has been declared - you should always work with classes in the same manner: before interacting with a particular class instance you have to create it using new operator.
Yes, unlike a base class you need to instantiate an inner class if you wish to use it.
You can prove this to yourself quite easily by trying it:
public class OuterClass
{
public InnerClass Ic { get; set; }
public class InnerClass
{
public InnerClass()
{
Foo = 42;
}
public int Foo { get; set; }
}
}
public class Program
{
static void Main()
{
Console.WriteLine(new OuterClass().Ic.Foo);
}
}
The above code throws a NullReferenceException because Ic has not been assigned.
I would also advise you to follow the Microsoft naming convention and use pascal case for type names.
In this case the answer doesn't depend on the fact that the class is defined inside your outer class. Because you used the automatic getter/setter, a hidden backing field is used for the property Ic. Like all fields of reference type, this field has a default value of null. Thus if you try to access the members of Ic without setting it to refer to some instance, you can expect a NullReferenceException.
Everything I just said would still be true even if innerClass was defined somewhere else.
No, the property is an instance of the class. The set would set a new instance anyway. No need to construct one unless you want to make sure the get never returns null.
Related
I would like to avoid writing the same line of code in all my derived classes. I have the following structure:
using Newtonsoft.Json;
public class BaseClass
{
public string BaseProperty { get; set; }
public string Serialize() { return JsonConvert.SerializeObject(this); }
}
public class DerivedClass : BaseClass
{
public string DerivedProperty { get; set; }
}
What happens when Serialize() is called from DerivedClass? Is this smart enough to know that the child object contains an extra property? Or, am I limited to writing this same line of code in each child of BaseClass?
Some language features / behaviors are easy to experiment with... Considering the following code:
public class A
{
public string WhoAmI => this.ToString();
}
public class B:A { }
Your question is equivalent to asking what Console.WriteLine(new B().WhoAmI) prints out?
Well, if in doubt, run it and see... it takes less than 1 minute.
this is a reference to an object, and behaves as any other reference, it simply has a special name.
Considere the following:
A a = new B();
Now you have a B instance referenced by an A typed reference a, but the instance is still a B. In your case this inside BaseClass is simply a BaseClass reference to whatever instance has been created. Do not confuse the type of a reference pointing to an object with the type of the object itself, they need not be the same.
I want to access class members that are in Class1 from another class (Class2) but I want to access it just from that class and to forbid access form any other class, form, etc. Is there any way to do this?
The only way to do this is to nest the classes, and then make the data private:
public class Class1
{
private object data;
public class Class2
{
public void Foo(Class1 parent)
{
Console.WriteLine(parent.data);
}
}
}
You can use nested class with private scope:
public class Class2
{
public Class2()
{
Class1 c1 = new Class1();
Console.WriteLine(c1.Id);
}
private class Class1
{
public int Id { get; set; }
}
}
Actually, you can do this with a bit of lateral thinking. One way is to create a method on Class1 that accepts an instance of Class2 and returns delegates to access the members which are marked private. Then declare Class2 as sealed to prevent someone sneaking in with inheritance.
Another way would be to inspect the call stack with a StackFrame in each member (fields are out for this) and throw an Exception if the caller isn't the desired type.
Lord knows.why you'd do this though! :)
You want a c# equivalent of "friend", but there isn't really one. This previous question gives possible solutions.
You can make an interface, that expose properties for access to your private members. And implement it explicitly. Than use that interface in other class.
2-nd way is to use reflection.
3-rd is nested classes.
you may implement a property
[IsAllowed(true)]
public class a
{
}
then at your,method you may change the sign of each method requiring the instance.
public class b {
public void method ( object aClassInstace){
.... Here check the property
}
}
I have the following class hierarchy:
public abstract class BaseClass : IBaseInterface
{
public int PropertyA{
get
{
return this.propertyA;
}
set
{
this.propertyA = value;
// ... some additional processing ...
}
}
}
DerivedClassB : BaseClass
{
// some other fields
}
public class ContainingClassC
{
public IBaseInterface BaseInterfaceObjectD
{
get;
set;
}
}
Now, in order to access PropertyA of a DerivedClassB-Object (inherited from BaseClass), I have to cast the object to BaseClassA's ancestor, like so:
// This ContainingClassC is returned from a static, enum-like class:
// containingObject.PropertyA is DerivedClassB by default.
ContainingClassC containingObject = new ContainingClassC();
((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42;
Is there a way I can restructure these classes to do away with the cast? This code is part of a library, and my colleague wants me to get rid of the cast.
The goal is to simply write containingObject.BaseInterfaceObjectD.PropertyA = 42.
First of all in the line ((IBaseInterface)containingObject.BaseInterfaceObjectD).PropertyA = 42; you are casting the member to the same type that it is declared in, so the casting doesn't actually do anything.
To be able to access the PropertyA in the derived class - since you are casting it to an interface - the property must be declared in the interface and then implemented in the BaseClass.
public interface IBaseInterface{
int PropertyA{get;set;}
}
public abstract class BaseClass : IBaseInterface{
public int PropertyA{
get{ return this.propertyA;}
set {this.propertyA = value;}
}
}
As long as the interface is implemented properly, ProprtyA should be available in the base class, the derived class or with either of them cast'ed to the interface type.
If it's just a problem of the property not showing up in IntelliSense, then it might be a problem with your settings. Check out Options->Text Editor->C# and make sure you have IntelliSense turned on and not set to hiding anythig.
I read other threads like this but they didn't work for me.
I got two classes:
public class ClassA
{
public string _shouldBeInteger;
public string _shouldBeBool;
public string _shouldBeDateTime;
}
public class ClassB : ClassA
{
public int? shouldBeInteger
{
get { return (_shouldBeInteger != null) ? Convert.ToInt32(Convert.ToDouble(_shouldBeInteger)) : new int?(); }
set { _shouldBeInteger = Convert.ToString(value); }
}
//... same thing with datetime etc.
}
If I now create a new object of ClassB I get
_shouldBeInteger, _shouldBeBool, _shouldBeDateTime;
shouldBeInteger,shouldBeBool,shouldBeDateTime
But I want to hide the _variables to the User.
Setting them private in ClassB will override them, but I need to access them in order to parse there string values.
Update
There is a ClassC filling ClassAs' values, which mainly is the reason why they have to be writeable. There is no way for me to change the way that works, but I'm fully in Control of ClassA and ClassB
ClassC //not changeAble for me
{
//infomagic filling values of ClassA
}
Setting ClassA variables to private won't work, because programmer of ClassA produced it in a strange way.
Solution
Because ClassA needs to be writeable, but not readable to other classes than inheritated, I finally got this:
ClassA
{
public string _shouldBeInteger { protected get; set; }
//and so on
}
which causes ClassB to work with theese properties, without giving them outside.
Intellisense still shows them, but you might consider using:
[EditorBrowsable(EditorBrowsableState.Never)]
to solve that.
Thanks to all.
I think you can solve your problem using:
public class ClassA
{
protected string _shouldBeInteger;
protected string _shouldBeBool;
protected string _shouldBeDateTime;
}
so those variables are accessible to derived classes but not to user.
EDITED after user update:
I don't know if this could be a vali solution for you, but try:
public class ClassB : ClassA
{
public new int? _shouldBeInteger
{
get { return (base._shouldBeInteger != null) ?
Convert.ToInt32(Convert.ToDouble(base._shouldBeInteger)) :
new int?(); }
set { base._shouldBeInteger = Convert.ToString(value); }
}
}
Inheritance can't hide the members as you would think. The new modifier exists to "hide" a base member, but that doesn't play nice when talking to base types.
http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
You can either change the access level of the fields (the preferred way) or you can wrap the class instead of inheriting from it and provide simple pass-through methods to delegate to the wrapped class. This is called the Adapter Pattern:
public class ClassB
{
private ClassA _wrappedClass;
}
Just as an aside, your public fields are following the naming convention commonly used for private fields.
The required access level for derived classes is protected. If the members are used publicly but in the same assembly you can use protected internal. If the members are used publicly by other assemblies... I'd suggest refactoring.
The problem is that you declared the fields public in the base class. In order not to violate the polymorphic nature of inheritance, anything public in the base class must be public in all derived classes as well. If you could change that, you could never be sure that a ClassB could be passed to something expecting a ClassA.
Therefore, as other people have suggested, you probably want the base class fields to be declared protected, which is like private except derived classes can see them.
However if you do need to access them via an actual instance of ClassA, you could declare them private and give them virtual public properties which the derived class can then override. This at least allows the derived class to change their behaviour, but it still can't actually hide them.
If that also doesn't fit, then it's probably worth considering using composition instead of inheritance because the substitution principle is actually getting in your way, and that's an inheritance fundamental.
If you don't have control over ClassA, you'll need to create a wrapper/adapter class like so:
public class ClassB
{
private readonly _classA = new ClassA();
public int? shouldBeInteger
{
get
{
return (this._classA._shouldBeInteger != null)
? Convert.ToInt32(Convert.ToDouble(this._classA._shouldBeInteger))
: new int?();
}
set
{
this._classA._shouldBeInteger = Convert.ToString(value);
}
}
}
public class ClassB
{
private int shouldBeInteger;
public int ShouldBeInteger
{
get { return shouldBeInteger; }
set { shouldBeInteger = value; }
}
}
OR
public class ClassB
{
public int ShouldBeInteger{ get; set; }
}
In both of this case ShouldBeInteger will be accesible outside the class.
In first case there were a private field, which cannot be accesible outside the class,
values to private filed can be set through the public field.
In second case the compiler automatically create a private backing field and do the same
process as above. This is auto implemented property.
Hope this may help you.
I have a class like the below, I want to override the set value of "School,Country..etc.." property when some one sets a value , i don't want to change the student class but i need to do it in the base class and use it as a generic method
public class Student : BaseClass
{
public String School { get; set; }
public String Country{ get; set; }
}
ie:
When some one sets
Student.School="Harvard",
I need to store it as
Student.School="Harvard my custom value";
Note:
Basically calling OnPropertyChanged in base class rather than the main class.
If you want to do it with aspects, then try Postsharp
Basically you cannot override a non-virtual property. You can hide it by other property with the same name in the derived class, but this won't give you the desired effect if some other code accesses your object by the reference to the base class.
public class Student : BaseClass
{
private string _school
public string School
{
get { return _school; }
set
{
if(value == "Harvard")
value = "Harvard custom";
_school = value;
}
}
public String Country{ get; set; }
}
is that what you mean?
If the School property is in the BaseClass then you can either use the new keyword, or if you control the BaseClass, then you can add the virtual keyword to the School property there, and override it in the Student class.
This is just not doable by solely modifying BaseClass. Think about it this way: If it were possible to "annotate" automatic properties that easily, then we wouldn't need all those <rant>useless tons of</rant> manual property implementations for data model classes that implement INotifyPropertyChanged (same for DependencyProperties).
You need to provide hooks in your subclasses that your base class can use. Implementing PropertyChanged, which you already mentioned, is one possible solution, another one would be a simple method call:
public class Student : BaseClass
{
private string _school;
public String School
{
get { return _school; }
set {
_school = value;
DoMoreChanges(ref _school); // DoMoreChanges is defined in BaseClass
}
}
public String Country{ get; set; }
}
If you have lots of subclasses that need this, you can either use Visual Studio Code Snippets to create the code or T4 templates.
Since your base class does not have those properties you will not be able to modify them from within the base class using standard OOD patterns or principles.
Now if you move the properties to your base class either as normal properties or virtual properties you can modify what you do in the set block of the properties to do extra work.
However if you cannot move these to the base class, and you cannot modify the Student class, as you seem to imply in you question, then you could encapsulate the student class within a new class like StudentProxy or something and then have it expose similar properties that will then call into the real student class how you want.
For example:
public class StudentProxy
{
private Student _student;
public StudentProxy(Student student)
{
this._student = student;
}
public String School
{
get { return _student.School; }
set
{
_student.School = value + " my custom value";
}
}
public String Country
{
get { return _student.Country; }
set
{
_student.Country = value + " my custom value";
}
}
}