I just came up with a really odd problem and I wasn't able to figure out how to solve it.
I have 3 classes, the class A is the base for B and C, that is:
class A { ... }
class B : A { ... }
class C : B { ... }
Now I would like to have a static property in these classes that stores the last object of each classes created, for example:
class A
{
static public A lastInstance;
}
class B : A
{
public B()
{
lastInstance = this;
}
}
class C : A
{
public C()
{
lastInstance = this;
}
}
What I would like to achieve is to be able to retrieve an instance for each subclass, for example:
var v1 = new B();
var v2 = new C();
var v3 = B.lastInstance; // v3 == v1 and v3 != v2
var v4 = C.lastInstance; // v4 == v2 and v4 != v3
Is it possible anyhow?
The only approach that seems promising to me shown in C# Static instance members for each inherited class: is it really the only chance I have to avoid defining a static member manually for each class?
I think this could be done with Dictionary and that's the only way i can think of right now:
class A {
static Dictionary<Type, A> _LastInstances = new Dictionary<Type, A>(); // because every subclass will inherit from A
public static A LastInstance {
get {
if ( _LastInstances.ContainsKey(GetType()) ) {
return _LastInstances[GetType()];
}
return null;
}
protected set {
if ( _LastInstances.ContainsKey(GetType()) ) {
_LastInstances[GetType()] = value;
} else {
_LastInstances.Add(GetType(), value);
}
}
}
class B : A {
public B(){
LastInstance = this;
}
}
At first: yes you can. But you missed two points with your implementation.
As you declared the lastInstance as public in class A every derived class can use it. As you declared it as static every instance of A will copy itself into it. But so will every instance of B, C and every other class with id derived from A: they all use the same instance. Thus the last instatiated class is saved and everything instantiated before is overwritten.
To overcome this, you must have a static property LastInstance (I switched to my naming convention) on every class, which you can accomplish by using the new modifier on derived classes
public class A
{
public static A LastInstance { get; private set; }
...
}
public class B : A
{
public static new B LastInstance { get; private set; }
...
}
But you're not done with that alone, because
When you create a new instance of B the (default-)construstor first makes a call into the construtor of A. Thus a reference to any already created instance of a base class is overwritten by the currently created instance of the derived class. So your constructors should look like this:
public class A
{
public static A LastInstance { get; private set; }
public A()
{
if (this.GetType() == typeof(A))
{
LastInstance = this;
}
}
}
public class B : A
{
public static new B LastInstance { get; private set; }
public B()
{
if (this.GetType() == typeof(B))
{
LastInstance = this;
}
}
}
This way you will get the correct lastly created instance (if any) in each classes static LastInstance.
Hope this helps
Because static members aren't inherited, you won't be able to access B.lastInstance if class A defines lastInstance. The suggestion you linked to seems reasonable. Although I don't have enough information on why you're attempting this, you could consider using a factory class that holds onto the latest created object.
Here's an example. This is not a good long term solution if you plan to have many classes deriving from A.
class HoldLastKnownFactory
{
B CreateB() { ... }
C CreateC() { ... }
B LastB { get {...} }
C LastC { get {...} }
}
Related
Is there a way, and not using reflection, of elegant get only child propeties of an object?
For example:
class A
{
public string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
/* Only class B properties without parent so B.PropB; but no B.PropA;
}
I know it would be possible with reflection, but if this can be avoided?
You could create a specific interface for your inherited class like say
interface ISpecificB {
string PropB;
}
and then Create your class like
public class A {
public string PropA;
}
public class B: A, ISpecificB {
public string PropB;
}
and only make the variable as specific as ISpecificB when creating it or returning it from a function
ISpecificB classB = new B();
classB.PropA // shouldn't be available
However, classB could still be casted as B or A which would give access to the propA and it might increase complexity in your solution
Whether you can do this way ?
class A
{
private string PropA;
}
class B : A
{
public string PropB;
}
class C
{
var classB_instance = new B();
}
You could mark PropA as private, look at https://msdn.microsoft.com/en-us/library/ms173121.aspx:
private
The type or member can be accessed only by code in the same class or struct.
just a short note: most of the time, I use reflection to do exactly the opposite: access things I am not allowed, for example, because they are private... ;-) reflection is not a "tool" to hide something, AFAIK. it opens every door which is usually locked ;-)
You can use the protected accessibility modifier:
The type or member can be accessed only by code in the same class or struct, or in a class that is derived from that class.
public class A
{
protected string PropA { get; set; }
}
public class B : A
{
public string PropB { get; set; }
}
public class C
{
var classB_instance = new B();
//You can't access classB_instance.PropA
}
Declare variable PropA of Class A as private variable(as show in below code):
class A
{
private string PropA;
}
I would like to restrict access to methods, depending on the type passed in. In my particular situation, I am developing a UDP "manager" if you will.
I want my UDPManager to be used for different things. For example, I might have 1 UDPManager for the communications between client and server, and another UDPManager to handle the communications between server and another server.
I have defined an enum which specifies the type of UDPManager. So for example, ManagerType.A = 1 and...
ManagerType.B = 2
The UDPManager has certain events that can be subscribed to and I do not want them available if these events are not relevant, given the type of UDPManager.
Here is an example of a class
public class Something
{
public int SomethingsType { get; set; }
public void A() { }
public void B() { }
}
How can I make it so that if SomethingsType == MessageType.A, then MessageType.B is not available (ie it is private)?
For further clarity, if I type:
Something something = new Something();
someting.SomethingsType = 1
I do not want something.B() to be available.
UPDATE
I apologise for mentioning runtime. What I mean is, I do not want said method (B) available if said SomethingsType is A.
Interfaces to the rescue:
public interface IUdpManagerA
{
void A();
}
public interface IUdpManagerB
{
void B();
}
public class UdpManager : IUdpManagerA, IUdpManagerB
{
public void A() { }
public void B() { }
}
public class UdpManagerFactory
{
private UdpManager Create() => new UdpManager();
public IUdpManagerA CreateOfA() => Create();
public IUdpManagerB CreateOfB() => Create();
}
UdpManagerFactory factory = new UdpManagerFactory();
IUdpManagerA a = factory.CreateOfA();
IUdpManagerB b = factory.CreateOfB();
Interfaces are a powerful tool to publish certain members while others can remain hidden.
While you might say yeah, but you can always cast IUdpManagerA to IUdpManagerB and vice versa to gain access to hidden members, and my answer is **this isn't safe because there's no clue that IUdpManagerA also implements IUdpManagerB and vice versa.
Oh, and I forgot to mention that you should throw away the ManagerType enumeration, because with interfaces you can always check if a given instance is A or B:
object instance = factory.CreateA();
if(instance is IUdpManagerA)
{
}
if(instance is IUdpManagerB)
{
}
or using as operator:
object instance = factory.CreateA();
IUdpManagerA a = instance as IUdpManagerA;
IUdpManagerB b = instance as IUdpManagerB;
if(a != null)
{
}
else if(b != null)
{
}
This is an extreme simple version of a factory build method based of an enum:
public enum ManagerType
{
A,B
}
public abstract class UDPManager
{
}
public class SomethingA : UDPManager
{
public void A()
{}
}
public class SomethingB : UDPManager
{
public void B()
{}
}
public class UdpManagerFactory
{
public UDPManager Build(ManagerType type)
{
if (type == ManagerType.A)
return new SomethingA();
if(type == ManagerType.B)
return new SomethingB();
throw new Exception("type not found");
}
}
I don't know if this is possible, but I am trying to get the Base Class instance from a Derived Class. In C#, I can use the base keyword to access properties and methods of the Base Class (of course), but I want to use base itself. Attempting to do so results in a "Use of keyword 'base' is not valid in this context" error.
Example Code
public class SuperParent
{
public int SPID;
public SuperParent()
{
}
}
public class SubChild : SuperParent
{
public SubChild(int pSPID)
{
base.SPID = pSPID;
}
public int BaseSPID
{
get
{
SuperParent sp = base;
return sp.SPID;
}
}
}
If you're working with an instance of the derived class, there is no base instance.
An example:
class A
{
public void Foo() { ... }
}
class B : A
{
public void Bar() { ... }
}
What is not possible within B:
public void Bar()
{
// Use of keyword base not valid in this context
var baseOfThis = base;
}
You can do something like this:
public void Bar()
{
base.Foo();
}
And you can add another method like
public A GetBase()
{
return (A)this;
}
And then you can
public void Bar()
{
var baseOfThis = GetBase();
// equal to:
baseOfThis = (A)this;
}
So this GetBase() method is probably what you want.
The punchline is: If you have an instance of B, it inherits all properties and the non-overriden behaviour of A, but it does not consist of an instance of B which holds an (hidden but automatic) reference to an instance of A. You can cast your B instance to A, but it remains to be an instance of B.
Well you not provide code for your question, but i supsect you want something like
class Base
{
public virtual void Foo()
{
Console.WriteLine("base");
}
}
class Derived : Base
{
public override void Foo()
{
Console.WriteLine("derived");
}
//// bad
//public Base MyBase
//{
// get
// {
// return base; // Use of keyword 'base' is not valid in this context
// }
//}
// work but...
public Base MyBase
{
get
{
return (Base)this;
}
}
}
But keep in mind that MyBase is really of type Derived
new Derived().MyBase.Foo(); // output "derived"
the problem hasn't been explained as clearly as it could. however, typically, you may be better to use an abstract base class and methods and then override the required methods. you can then use the base.method as required in this case (otherwise you'll have just spun up an instance of the derived class).
public abstract class foo {
public virtual void bar(){..}
}
public class footwo : foo {
public override void bar(){
// do somethng else OR:
return base.bar();
}
}
}
The derived instance IS the base instance. It's just one object instance in memory.
example:
public class A : B
{
}
var thing = new A();
thing is an instance of an A, and is also an instance of a B.
You could for example, write this line:
B thing2 = thing;
Point 1: if you want to create the base class instance within child class than it does not worth. You already have public things accessible in child.
Point 2: If you have initialized child class and now want to get base class "instance" then how can you get that if it's not initialized(Because now the base class instance is not present in the physical memory, and there is just child class instance there)?
I interpreted what they were asking a bit differently than the other answers here so I figured I would offer my $0.02.
// Create a "Parent" class that has some attributes.
public class Parent
{
public string attribute_one { get; set; }
public string attribute_two { get; set; }
public string attribute_three { get; set; }
}
// Define a class called "Child" that inherits the
// attributes of the "Parent" class.
public class Child : Parent
{
public string attribute_four { get; set; }
public string attribute_five { get; set; }
public string attribute_six { get; set; }
}
// Create a new instance of the "Child" class with
// all attributes of the base and derived classes.
Child child = new Child {
attribute_one = "interesting";
attribute_two = "strings";
attribute_three = "to";
attribute_four = "put";
attribute_five = "all";
attribute_six = "together";
};
// Create an instance of the base class that we will
// populate with the derived class attributes.
Parent parent = new Parent();
// Using reflection we are able to get the attributes
// of the base class from the existing derived class.
foreach(PropertyInfo property in child.GetType().BaseType.GetProperties())
{
// Set the values in the base class using the ones
// that were set in the derived class above.
property.SetValue(parent, property.GetValue(child));
}
The result is a new object populated with the base class properties of the child class.
class Parent
{
private Parent _parent;
public Parent()
{
_parent = this;
}
protected Parent GetParent()
{
return _parent;
}
}
class Child : Parent
{
private Parent _parent;
public Child()
{
_parent = base.GetParent();
}
}
I want to hide the base public property(a data member) in my derived class:
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class a
{
public int item1 {get; set;}
public int item2 { get; set; }
}
class b : a
{
new private int item1;
}
class c : a
{
}
i have member as public because i want the member to be inherited in c class , but want to hide the member in b class , how can i do this ?
dont i have an option to selectively inherite the variable i want in my base class ??? thats really bad , i think ms should provide us with an option (may be a modifier) to perform this
Edit:
I found the answer myself (i heard lots of them telling this is not possible in c#, but you can kind of do it)
I am including the code in case it is useful
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4; // shows an error : )
}
}
class a
{
public int item1 { get; set; }
public int item2 { get; set; }
}
class b : a
{
new public static int item1
{
get;
private set;
}
}
I'm going to attempt to explain with examples why this is a bad idea, rather than using cryptic terms.
Your proposal would be to have code that looks like this:
public class Base
{
public int Item1 { get; set; }
public int Item2 { get; set; }
}
public class WithHidden : Base
{
hide Item1; // Assuming some new feature "hide" in C#
}
public class WithoutHidden : Base { }
This would then make the following code invalid:
WithHidden a = new WithHidden();
a.Item1 = 10; // Invalid - cannot access property Item1
int i = a.Item1; // Invalid - cannot access property Item1
And that would be just what you wanted. However, suppose we now have the following code:
Base withHidden = new WithHidden();
Base withoutHidden = new WithoutHidden();
SetItem1(withHidden);
SetItem1(withoutHidden);
public void SetItem1(Base base)
{
base.Item1 = 10;
}
The compiler doesn't know what runtime type the argument base in SetItem1 will be, only that it is at least of type Base (or some type derived from Base, but it can't tell which -- it may be obvious looking at the code snippet, but more complex scenarios make it practically impossible).
So the compiler will not, in a large percentage of the cases, be able to give a compiler error that Item1 is in fact inaccessible. So that leaves the possibility of a runtime check. When you try and set Item1 on an object which is in fact of type WithHidden it would throw an exception.
Now accessing any member, any property on any non-sealed class (which is most of them) may throw an exception because it was actually a derived class which hid the member. Any library which exposes any non-sealed types would have to write defensive code when accessing any member just because someone may have hidden it.
A potential solution to this is to write the feature such that only members which declare themselves hideable can be hidden. The compiler would then disallow any access to the hidden member on variables of that type (compile time), and also include runtime checks so that a FieldAccessException is thrown if it is cast to the base type and tried to be accessed from that (runtime).
But even if the C# developers did go to the huge trouble and expense of this feature (remember, features are expensive, especially in language design) defensive code still has to be written to avoid the problems of potential FieldAccessExceptions being thrown, so what advantage over reorganising your inheritance hierarchy have you gained? With the new member hiding feature there would be a huge number of potential places for bugs to creep into your application and libraries, increasing development and testing time.
What you want to do goes directly against the grain of OO, you can't 'unpublish' members as this violates the substitution principle. You have to refactor this into something else.
Vadim's response reminded me of how MS achieve this in the Framework in certain places. The general strategy is to hide the member from Intellisense using the EditorBrowsable attribute. (N.B. This only hides it if it is in another assembly) Whilst it does not stop anyone from using the attribute, and they can see it if they cast to the base type (see my previous explination) it makes it far less discoverable as it doesn't appear in Intellisense and keeps the interface of the class clean.
It should be used sparingly though, only when other options like restructuring the inheritance hierarchy would make it a lot more complex. It's a last resort rather than the first solution to think of.
If you use an interface instead of a base class for defining the property, you could implement the property explicitly. The would require an explicit cast to the interface to use the property.
public interface IMyInterface
{
string Name { get; set; }
}
public class MyClass : IMyInterface
{
string IMyInterface.Name { get; set; }
}
You can find more out here.
The only thing I can think of is to make item1 virtual in class a:
class a
{
public virtual int item1 { get; set; }
public int item2 { get; set; }
}
and then override it in class b but throw an exception in getter and setter. Also if this property is used in a visual designer you can use Browsable attribute to not display.
class b : a
{
[Browsable(false)]
public override int item1
{
get
{
throw new NotSupportedException();
}
set
{
throw new NotSupportedException();
}
}
}
First of all this is not good idea if you using some methods, that operates base class.
You can try to use obsolete argument to make users twice think to use this property.
[System.Obsolete("Do not use this property",true)]
public override YourType YourProperty { get; set; }
What you are describing is something akin to 'private inheritance' from C++, and is not available in C#.
You cant do it directly, but you could override the properties in the child class and make them readonly e.g.
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class a
{
public virtual int item1 {get; set;}
public virtual int item2 { get; set; }
}
class b : a
{
public override int item1
{
get { return base.item1; }
set { }
}
}
class c : a
{
}
You could use interfaces to hide the property. The child class would implemented an interface that didn't have the property then it wouldn't appear.
You would need two interfaces for when you want the property and when you don't, thus making it a horrible hack.
You can override it and then Add a [Browsable(false)] tag to prevent showing it in designer.
Simple:
public class a:TextBox
{
[Browsable(false)]
public override string Text
{
get { return ""; }
set { }
}
}
Changing the accessibility of a virtual member is an inheriting class is specifically prohibited by the C# language spec:
The override declaration and the overridden base method have the same
declared accessibility. In other words, an override declaration cannot
change the accessibility of the virtual method. However, if the
overridden base method is protected internal and it is declared in a
different assembly than the assembly containing the override method
then the override method’s declared accessibility must be protected.
From section 10.6.4 Override methods
The same rules which apply to overriding method also apply to properties, so going from public to private by inheriting from the base class can't be done in C#.
What you actually need are interfaces:
public interface ProvidesItem1
{
int item1 { get; set; }
}
public interface ProvidesItem2
{
int item2 { get; set; }
}
class a : ProvidesItem1, ProvidesItem2
{
public int item1 { get; set; }
public int item2 { get; set; }
}
class b : ProvidesItem1
{
public int item1 { get; set; }
}
Then just pass the interfaces around. If the classes should use a common implementation, put that in a third class and let them derive from that class aswell as implement their respective interface.
Yes, it is possible. What say you on the delegation. I will try to give an idea of what is called "delegation" in OOP with a piece of code:
public class ClassA
{
// public
public virtual int MyProperty { get; set; }
// protected
protected virtual int MyProperty2 { get; set; }
}
public class ClassB
{
protected ClassC MyClassC;
public ClassB()
{
MyClassC = new ClassC();
}
protected int MyProperty2
{
get { return MyClassC.MyProperty2; }
set { MyClassC.MyProperty2 = value; }
}
protected int MyProperty
{
get { return MyClassC.MyProperty; }
set { MyClassC.MyProperty = value; }
}
protected class ClassC : ClassA
{
public new int MyProperty2
{
get { return base.MyProperty2; }
set { base.MyProperty2 = value; }
}
public override int MyProperty
{
get { return base.MyProperty; }
set { base.MyProperty = value; }
}
}
}
namespace PropertyTest
{
class a
{
int nVal;
public virtual int PropVal
{
get
{
return nVal;
}
set
{
nVal = value;
}
}
}
class b : a
{
public new int PropVal
{
get
{
return base.PropVal;
}
}
}
class Program
{
static void Main(string[] args)
{
a objA = new a();
objA.PropVal = 1;
Console.WriteLine(objA.PropVal);
b objB = new b();
objB.PropVal = 10; // ERROR! Can't set PropVal using B class obj.
Console.Read();
}
}
}
You can user new modifer.
Sample;
public class Duck
{
public string Color{get; set;}
public void Swim() { }
}
public class DonaldDuck : Duck
{
new public void Swim()
{
/*you could call in DonaldDuck.Swim only here but not public for DonaldDuck client.*/
}
}
If you wanna hide a member from base class then you will need to add a new base class let's call it baseA and your code should be as follows:
class Program
{
static void Main(string[] args)
{
b obj = new b();
obj.item1 = 4;// should show an error but it doent ???
}
}
class baseA
{
public int item2 { get; set; }
}
class a:baseA
{
public int item1 { get; set; }
}
class b : baseA { }
class c : a { }
Here is my code (just a snippet to expose the problem) :
public class A
{
class B
{
//private class
}
public int nb;
}
Im tired but why can't I access to "nb" in my private class ?
You're gonna need an instance of A in order to access the instance member nb:
public class A
{
class B
{
public B()
{
A a = new A();
int nb = a.nb;
}
}
public int nb;
}
It's possible in java but not in C#.
You need to pass an instance of A to B.
In C# an 'outer' class is just a 'namespace' to the inner class. So the outer class is not being instantiated.
You need to pass an instance of A to B, like so:
public class A
{
class B
{
private A _outerClass;
public B(A outerClass)
{
_outerClass = outerClass;
// Then you can access nb thus:
_outerClass.nb;
}
}
public int nb;
}