I am looking to get a child class instantiated using a parent instance to set all of the inherited variables.
For example:
public class Foo
{
//Variables
}
public class bar : Foo
{
public int ID { get; set; }
public bar(Foo instance)
{
base = instance; // Doesn't work but is generally the idea I'm looking for
}
}
Just add a constructor to your parent Foo class that accepts a Foo instance and takes care of copying the fields. The Bar class can then invoke that as the base constructor.
public class Foo
{
private string var1;
private string var2;
public Foo() { }
public Foo(Foo otherFoo)
{
this.var1 = otherFoo.var1;
this.var2 = otherFoo.var2;
}
}
public class Bar : Foo
{
public int ID { get; set; }
public Bar(Foo instance)
: base(instance)
{
}
}
You would have to make all your members public inside Foo that would need to be set from the constructor. Then, set the properties you need to.
I think you are looking for some kind of mapper that maps from one object to another.
You could use a open source project like AutoMapper or ValueInjecter which can be found on NuGet.
Here is also a nice article:
Copy values from one object to another
Demo with ValueInjecter:
static void Main(string[] args)
{
var foo = new Foo()
{
Property1 = "Value1",
Property2 = "Value2"
};
var bar = Mapper.Map<Bar>(foo);
bar.Id = 3;
Console.WriteLine(bar.Id); //3
Console.WriteLine(bar.Property1); //Value1
Console.WriteLine(bar.Property2); //Value2
}
Why can't you get it done through a public auto property like below. BTW, what you are trying to have is Composition wherein bar object is composed of foo object. Not sure why you are still inheriting from foo then?
public class bar : Foo
{
public int ID { get; set; }
public Foo baseinstance { get; set;}
public bar(Foo instance)
{
baseinstance = instance;
}
}
I am not absolutely sure but from your posted code (specifically the below part) it feels like you are trying to call the base class constructor or constructor initializer since you said
I am looking to get a child class instantiated using a parent instance
to set all of the inherited variables.
public bar(Foo instance)
{
base = instance;
}
Which should actually be
public bar(Foo instance) : base()
{
//child instance initialization
}
But that's not needed for a parameterless constructor cause when you instantiate child object constructor initializer will get invoked and base class will gets initialize first in-order to have the base member initialized before child initialization.
If you have parameterized constructor in base and in child then you can explicitly call base constructor
Related
abstract class Foo
{
private readonly FooAttributeCollection attributes;
public Foo(FooAttributeCollection attributes)
{
this.attributes = attributes;
}
}
class FooAttributeCollection
{
public FooAttributeCollection(Foo owner)
{
}
}
class Bar : Foo
{
public Bar() : base(new FooAttributeCollection(this))
{
}
}
Supposing that I have to write a code like above. and the classes Foo and FooAttributeCollection cannot be modified.
When I write Bar class like that, an error mentioned below:
'this' keyword cannot be used in this context.
occurs near the line base(...)
Is there any good idea to handle with this matter?
If Foo and FooAttributeCollection can't be modified, this code seems to be a bad design.
To instantiate a derivated Foo class you must instantiate FooAttributeCollection before and to instantiate FooAttributeCollection you must instantiate the same derivated Foo class.
Its a endless circular dependency impossible to resolve without 'cheating'
perhaps this problem can be resolve by refection (as say by Uwe Keim), or by using real proxy/dynamic proxy to create a proxy of DerivedClass.
Why don't affect attributes in abstract class ? If you want in FooAttributeCollection you can cast owner in Bar class.
abstract class Foo
{
private readonly FooAttributeCollection attributes;
public Foo(FooAttributeCollection attributes=null)
{
if(attributes = null) {attributes = new FooAttributeCollection(this);}
this.attributes = attributes;
}
}
class FooAttributeCollection
{
public FooAttributeCollection(Foo owner)
{
var ownerInBar = owner as Bar;
}
}
class Bar : Foo
{
public Bar() : base()
{
}
}
You can't write:
public Bar() : base(new FooAttributeCollection(this))
Because this, the current object, must be put in the implementation of a method, not in the method signature: here you have no access to the current instance of the object.
You can't do a such thing in every method declaration because you are out of the implementation scope, you are in the type def scope i.e. in the "interface" of the class, in its definition.
The use of calling base or side constructor with base or this keyword is a particular language construction to pass parameters that are not the instance of the class itself.
You can use the #Tohm solution to solve your goal.
the class needs to be constructed before you can access the this keyword.
You can try the bellow.
class Bar : Foo
{
private readonly FooAttributeCollection attributes;
public Bar() : base(null)
{
var attributes = new FooAttributeCollection(this);
}
}
Try this way:
public class Bar : Foo
{
public Bar(FooAttributeCollection attributes) : base(attributes)
{
}
}
Other Example:
public class BaseClass
{
int num;
public BaseClass(int i)
{
num = i;
Console.WriteLine("in BaseClass(int i)");
}
}
public class DerivedClass : BaseClass
{
// This constructor will call BaseClass.BaseClass(int i)
public DerivedClass(int i) : base(i)
{
}
}
I'm confused about this statement:
ctrlID.Font.Size = FontUnit.Small;
but FontUnit is a struct under System.Web.UI.WebControls
public struct FontUnit
{
...
public static readonly FontUnit Small;
...
}
as a struct is a class, so how can we have a class A that has its self as a object like:
public class A{
public A a;
}
isn't it like creating an endless chain of objects which would require infinite memory?
The property is static, so it's a member of the Type, and not of the object instance. You do not need to construct the Small static property to create a FontUnit object.
Consider this:
public class Foo
{
public static Foo Default {get;}
static Foo()
{
Default = new Foo();
}
}
Default is only constructed once, at an unknown time before it is used.
If it's not static, you can get into the behavior you expected.
public class Foo
{
public Foo Default {get; private set;}
public Foo()
{
Default = new Foo();
}
}
This will cause an overflow, as the property will keep instantiating a new Foo, which will make a new Foo, and so on.
So long as you're careful not to instantiate a type with the same constructor you are currently instantiating a type in there shouldn't be any issue with a type having member of it's own type.
I have a class A, and a class AStore. My requirement is to prevent all other methods from initializing an instance of class A, which they should get an instance from AStore. In addition, I also need to access the member functions of A from the instance.
Factory pattern is not suitable for this problem as the constructor of A is still public. Ideally, it should throw compilation error when calling the constructor of class A while having access to its member functions.
Can I get C# solutions to this?
For restricting others to create an instance of class A you can use a private constructor and a static factory method to get the instance of that class.
public class A
{
private A(){}
public static A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
To enforce instance creation of A only via Astore you can use protected modifier and derive AStore from A. That way, only AStore will have access to its protected members like 'constructor' or 'factory method':
public class Astore : A
{
public A GetInstanceOfA()
{
return base.GetInstance();
}
}
public class A
{
protected A() { }
protected A GetInstance()
{
return new A();
}
public void MemberFunctionOfA()
{
// blah blah...
}
}
//Usage
public class ConsumerClass
{
public void Test()
{
var a = new A(); // Compile error
a = new Astore().GetInstanceOfA();
a.MemberFunctionOfA();
}
}
But there're still chances that another class say 'UnWantedStore' can derive from A and serve instance of A.
Another approach is moving AStore and A classes to the dedicated project and make constructor of A class internal.
// Project A
namespace ProjectA
{
public class A
{
public int PropertyOne { get; set; }
public string PropertyTwo { get; set; }
internal A() {}
}
public class AStore
{
public A CreateA()
{
//internal constructor can be used
return A();
}
}
}
// Project ConsumerOfA
namespace ConsumerOfA
{
public static void UseA()
{
var store = new AStore();
var instanceOfA = store.CreateA();
// have access to the A's public members
}
}
With this approach you will get perfect encapsulation you trying to achive.
Abstract classes to the rescue!
Indeed, there's yet another possible approach! I've never used it but it might work in your scenario. See the following code sample:
public abstract class A
{
public string Text { get; set; }
public string SayHello() => "hello world!";
}
public class AStore
{
private class AInternal : A {}
public void DoStuff()
{
A a = new AInternal();
a.Text = "whatever";
string helloText = a.SayHello();
}
}
Let's explain the approach:
Class A is abstract, therefore it can't be instantiated.
Class AStore implements a private nested class called AInternal which just inherits A to let AStore members be able to instantiate A. Since AInternal is private, no other class than AStore can instantiate AInternal!
Class AStore can access public A members because AInternal inherits A!
You can do this with reflection too:
public class ClassA
{
// The constructor(s) have to be private
private ClassA() { }
// Whatever other code you want
}
public class ClassB
{
public static ClassA GetClassAInstance()
{
// Use reflection to get the private default constructor
ConstructorInfo constructor = typeof(ClassA).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);
ClassA instance = constructor.Invoke(new object[] { }) as ClassA;
return instance;
}
}
You can find more information on the GetConstructor method here.
I have a class Foo that has a field _customObject that must be initialized. I also have a class Bar that inherits from Foo:
public abstract class Foo
{
protected CustomObject _customObject;
public Foo()
{
// Do stuff
}
// Other methods that use _customObject
}
public class Bar : Foo
{
// Constructor and other methods
}
I can not initialize the object _customObject in Foo because every child inherited contains a different child of CustomObject, so it must be initialized in every child class:
public class Bar : Foo
{
public Bar()
{
_customObject = new CustomObjectInherited1();
}
}
public class Baz : Foo
{
public Baz()
{
_customObject = new CustomObjectInherited2();
}
}
Other people are going to implement new classes that inherit from Foo, so I was wondering if there is a way that an error in build time is shown, similar to when an abstract method is not implemented. If CustomObject is not initialized, a NullReferenceException will be thrown due to the use of the _customObject variable, ending in an application crash.
You can add a parameter to your Foo constructor:
public abstract class Foo
{
protected CustomObject _customObject;
public Foo(CustomObject obj)
{
// Do stuff
_customObject = obj;
}
// Other methods that use _customObject
}
Your derived classes will then be forced to call it, passing in a CustomObject, or something derived from it:
public class Bar : Foo
{
public Bar():base(new CustomObjectInherited1())
{
}
}
Not calling the base constructor will result in a compile time error. This doesn't entirely protect you, as someone could still pass null to the base constructor, but at least they'll have an explanation as to why they're getting a NullReferenceError at runtime.
You can force it by creating a abstract method which requires child classes to override it.
public abstract class Foo
{
protected abstract CustomObject CreateCustomObject();
}
public class Bar : Foo
{
protected override CustomObject CreateCustomObject()
{
return new BarCustomObject();
}
}
Or my favorite solution: Enforce it by generic constraints.
public abstract class Foo<T> : where T : CustomObject, new()
{
protected T _customObject;
public Foo()
{
this.CustomObject = new T();
}
}
public class Bar : Foo<BarCustomObject>
{
}
The answer provided by "James Thorpe" is correct (I've upvoted it already), but I wanted to share just another option here:
You could mark your class as abstract and introduce an abstract property instead of the "_customObject" field. That way, at least the first initializer will be forced to implement it. The downside is that you'll loose the enforcement on subsequent level subclasses:
public abstract class Foo
{
protected abstract CustomObject CustomObject {get; }
public Foo()
{
// Do stuff
}
// Other methods that use _customObject
}
public class Bar : Foo
{
// Constructor and other methods
protected override CustomObject CustomObject
{
get { return "X"; }
}
}
Also, with the first solution it's possible to validate the passed in value in the constructor - though, that'll be a runtime validation.
I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();