public BaseClass
{
prop abc;
prop pqr;
prop xyz;
}
public DerivedClass : BaseClass
{
prop New1;
prop New2;
//constructor
public DerivedClass(BaseClass baseObj,someMore params)
{
this.abc = baseObj.abc;
this.pqr = baseObj.pqr;
this.xyz = baseObj.xyz;
/* I do not want to do this for each and every property as I have more than 40 properties */
}
}
Here in above code How I can set all properties of derived class which are same in derived class as base class.
In my derived class
Can I do somethign of following type to achieve above thing without using Automapper or Reflection
public DerivedClass(BaseClass baseObj,someMore params):base(baseObj) //or something similar
{
}
You could initialize the properties in your base class instead of the derived class (since both the parameter and the base classes share the same type of class).
To copy the properties, besides AutoMapper (which I find really slow) and reflection (which is hard to implement and maintain), an easy, very efficient way to do this is using the open source library Omu.ValueInjecter:
Install the library from NuGet:
Install-Package ValueInjecter -Version 3.1.3
Then, use it in your constructor as follows:
using Omu.ValueInjecter;
public abstract class BaseClass
{
protected BaseClass(BaseClass baseObj)
{
this.InjectFrom(baseObj);
}
public string Abc { get; set; }
public int Pqr { get; set; }
public object Xyz { get; set; }
}
public class DerivedClass : BaseClass
{
public DerivedClass(BaseClass baseObj, int new1, object new2) : base(baseObj)
{
New1 = new1;
New2 = new2;
}
public int New1 { get; set; }
public object New2 { get; set; }
}
The first time you run this code, it will create a mapper and store it in memory so the following times you perform the same operation will be much faster.
If you don't want to use value injecter or any other library, simply set the properties manually in your base class.
public abstract class BaseClass
{
protected BaseClass(BaseClass baseObj)
{
Abc = baseObj.Abc;
Pqr = baseObj.Pqr;
Xyz = baseObj.Xyz;
}
[...]
}
You can use prototype pattern. If you use C#, Please refer code as below:
public abstract class BaseClass
{
public int a;
public int b;
public int c;
public abstract BaseClass Clone();
}
public class DerivedClass : BaseClass
{
public int new1;
public int new2;
public override BaseClass Clone()
{
return this.MemberwiseClone() as BaseClass;
}
public override string ToString()
{
return string.Format("{0}{1}{2}{3}{4}", a, b, c, new1, new2);
}
}
class Program
{
static void Main(string[] args)
{
DerivedClass AClass = new DerivedClass();
AClass.a = 1;
AClass.b = 2;
AClass.c = 3;
DerivedClass BClass = AClass.Clone() as DerivedClass;
BClass.new1 = 4;
BClass.new2 = 5;
Console.WriteLine(BClass.ToString());
}
}
It comes from https://mobilechos.blogspot.com/2019/04/prototype-pattern-with-csharp.html.
Related
Say I have the following
public class A{
public string foo {get;set;}
public string bar {get;set;}
public int baz {get;set;}
}
public class B:A
{
public string wuz {get;set;}
}
public class C:A
{
public int yuh {get;set;}
}
If I then make an instance of B
var b = new B(){wuz="wow",foo="hello",bar="wordl",baz=18};
and later on I want to use those values of B in C, then I have to manually write
c = new C(){yuh=20, foo = b.foo, bar = b.bar, baz=b.baz};
isn't there a way to make c take the already instantiated values from B in a dynamic way, and parse them onto C? In this example it is easy to to, but say I have 500 properties then it's not feasible
(I'm fairly new to .NET thus there might be a typo/syntax error in the codeexample above, but I think the problem should be rather clear)
You can add a constructor to C that takes an instance of A (or if you really want to do that B). Would look something like this:
public class C:A
{
public C() {}
public C(A other)
{
this.foo = other.foo;
...
}
public int yuh {get;set;}
}
If you also want the same capability in B, you might want to add this kind of constructor to A, and call it from C:
public class A{
public A(){}
public A(A other)
{
this.foo = other.foo;
...
}
public string foo {get;set;}
public string bar {get;set;}
public int baz {get;set;}
}
public class C:A
{
public C(){}
public C(A other) : base(other) {}
public int yuh {get;set;}
}
In either case you can now create a new instance of Clike this:
c = new C(b){ yuh = 20};
Yes you can. You need to write method that will take B instance and sets all properties with reflection.
public C CreateCFromB(B bInstance)
{
var cInstance = new C();
foreach (var property in typeof(B).GetProperties())
{
var propertyValue = property.GetValue(bInstance, null);
property.SetValue(cInstance, propertyValue);
}
return cInstance;
}
You can take more generalized approach with generic types.
public TWhat CreateFrom<TFrom, TWhat>(TFrom tFromInstance)
where TWhat : TFrom, new()
{
var tWhatInstance = new TWhat();
foreach (var property in typeof(TFrom).GetProperties())
{
var propertyValue = property.GetValue(tFromInstance, null);
property.SetValue(tWhatInstance, propertyValue);
}
return tWhatInstance;
}
I have the following base class:
public class Base
{
public string LogicalName { get; set; }
public int NumberOfChars { get; set; }
public Base()
{
}
public Base(string logicalName, int numberOfChars)
{
LogicalName = logicalName;
NumberOfChars = numberOfChars;
}
}
and the following derived classes:
public class Derived1 : Base
{
public const string EntityLogicalName = "Name1";
public const int EntityNumberOfChars = 30;
public Derived1() : base(EntityLogicalName, EntityNumberOfChars)
{
}
}
public class Derived2 : Base
{
public const string EntityLogicalName = "Name2";
public const int EntityNumberOfChars = 50;
public Derived2()
: base(EntityLogicalName, EntityNumberOfChars)
{
}
}
and I also have this function that is provided by a service:
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
//Some code to get the entities
}
My problem is how can I call this function generically? I want to call it with something that looks like this:
public void TestEntities<T>() where T : Base
{
var entities = GetEntities<T>(T.EntityLogicalName, T.EntityNumberOfChars);
//some other code to test the entities
}
This of course doesn't work because at this point T is not known. How can I accomplish something similar to this? EntityLogicalName and EntityNumberOfChars are characteristics that all Base derived classes have and they never change for each derived class. Can I get them from the Base class without instantiating objects or some other way that I am not seeing?
Replace constants with getter abstract properties
public abstract class Base
{
public abstract string LogicalName { get; }
public abstract int NumberOfChars { get; }
public Base()
{
}
}
public class Derived1 : Base
{
public string LogicalName { get { return "Name1"; } }
public int NumberOfChars { get { return 30; } }
public Derived1() : base()
{
}
}
Also, you will be able to put some logic into overriden getter, e.g. :
...
public string LogicalName { get { return this.EntityMap.Name; } }
...
UPDATE: The fact that you do not want to instantiate object from class but want to be able to get that string in a strongly typed manner can be handled in one more way. It is totally separate from answer above ( Since you can't override static props in c#). Consider the following code. We are adding one more class here, but LocatorInner can be a member of BaseClass. We are using this approach a lot in several existing apps.:
public class Locator
{
public static class LocatorInner<T> where T : BaseClass
{
public static string Name { get; set; }
}
public static string GetName<T>() where T : BaseClass
{
return LocatorInner<T>.Name;
}
public static void SetName<T>(string name) where T : BaseClass
{
LocatorInner<T>.Name = name;
}
}
public class BaseClass
{
}
public class DerivedClass: BaseClass
{
static DerivedClass()
{
Locator.LocatorInner<DerivedClass>.Name = "me";
}
}
public class TestClass<T> where T : BaseClass
{
public void Method()
{
var name = Locator.GetName<T>();
}
}
IMHO, I believe using constants here is a bad design decision.
You can either solve the issue using #vittore approach, but for me it sounds like you should use meta-programming with attributes if you're looking to get data from the T generic argument
For example, what about:
public class LogicalNameAttribute : Attribute
{
public LogicalNameAttribute(string name)
{
Name = name;
}
public string Name { get; private set; }
}
public class NumberOfCharsAttribute : Attribute
{
public NumberOfCharsAttribute (int number)
{
Number = number;
}
public string Number { get; private set; }
}
[LogicalName("Name1"), NumberOfChars(30)]
public class Derived1 : Base
{
public Derived1() : base()
{
}
}
Now your service method can extract attribute metadata as follows:
public void TestEntities<T>() where T : Base
{
LogicalNameAttribute logicalNameAttr = typeof(T).GetCustomAttribute<LogicalNameAttribute>();
NumberOfCharsAttribute numberOfCharsAttr = typeof(T).GetCustomAttribute<NumberOfCharsAttribute >();
Contract.Assert(logicalNameAttr != null);
Contract.Assert(numberOfCharsAttr != null);
string logicalName = logicalNameAttr.Name;
int numberOfChars = numberOfCharsAttr.Number;
// Other stuff
}
There's a performance penalty because you need to use reflection to get attributes applied to T, but you gain the flexibility of not forcing derived classes to provide this static info.
As #vittore mentioned, move the properties to base,pass the hard coded values from derived and in creation use just defautl(T)
public IEnumerable<T> GetEntities<T>(string entityName, int numberOfChars) where T : Base
{
yield return default(T); //Is its always class use new constraint and return new T();
}
Actually, I want to access properties of a base class in a method and I am not instantiating that object directly. Below is code, I am working on:
public class Test
{
public static void Main()
{
drivedclass obj = new drivedclass();
obj.DoSomething();
}
}
public class drivedclass : baseclass
{
public void DoSomething()
{
LoadSomeThing();
}
}
public class baseclass
{
public string property1
{
get;
set;
}
public string property2
{
get;
set;
}
public void LoadSomeThing()
{
//here I want to access values of all properties
}
}
I would like to know if there is a way, I can access the properties in method of same class and that class is base class.
You can just use property1 and property2 as they are.
However, note that in LoadSomeThing() you will not be able to access any properties of drivedlcass, because base classes cannot see properties of their derived classes by definition.
You can access them with reflection, but this is not the 'normal' way.
foreach(PropertyInfo prop in this.GetType().GetProperties())
{
prop.SetValue(this, newValue);
}
If you want to make it 'cleaner', you should make the properties virtual.
Use the following method to enumerate all property values:
public void EnumerateProperties()
{
var propertiesInfo = this.GetType().GetProperties();
foreach (var propertyInfo in propertiesInfo)
{
var val = propertyInfo.GetValue(this, null);
}
}
Question is quiet unclear but if you wish to access your properties, they are well present in both the Base class and the derived class. thus, if you do s = obj.property2 in your main class Test, that should be available.
public class Test {
public static void Main( ) {
drivedclass obj = new drivedclass( );
obj.DoSomething( );
string s = obj.property2 ;
}
}
You could always make it explicit:
public class DerivedClass : BaseClass
{
public string Property3
{ get; set; }
public void DoSomething ()
{
LoadSomeThing();
}
public override void LoadSomeThing ()
{
base.LoadSomeThing();
Console.WriteLine(Property3);
}
}
public class BaseClass {
public string Property1
{ get; set; }
public string Property2
{ get; set; }
public virtual void LoadSomeThing()
{
Console.WriteLine(Property1);
Console.WriteLine(Property2);
}
}
You can simply try: this.property1
how to implement a const field which in subClasses must be overwrite, i'm using .net 4, C#
because i have many classes they all have a const field(with different value) called 'pName'.
so i want use a interface or abstract class or somthing as a parent and force these classes to override it.
it's CONST field
You cannot override a const; nor can you declare it as static and override it there. What you can do is re-declare it, but that is not robust - in that which version gets used depends on which you ask for (entirely at compile-time - completely unrelated to polymorphism):
public new const int Foo = 12;
I would suggest you use a virtual or abstract property:
public virtual int Foo { get { return 4; } } // subclasses *can* override
public abstract int Foo { get; } // subclasses *must* override
and override:
public override int Foo { get { return 12; } }
You request is contradictional: you can not define a constant value which is possible to override, so change in derived class.
What you can do is define default value in base class, and override it in derived one.
public class Base
{
public static reaondly int DEFAULT_BASE_VALUE = 0,
private int _someValue = DEFAULT_BASE_VALUE; //ASSIGN DEFAULT VALUE
public virtual int SomeValue {
get {
return _someValue;
}
}
}
public class Derived : Base
{
public override int SomeValue {
get {
return -3; //CHANGE VALUE OF BASE CLASS
}
}
}
You can't. What you can do is declare a abstract readonly property like so
abstract class A
{
public abstract int ReadOnlyProp {get;}
}
class B : A
{
public override int ReadOnlyProp
{
get { return 42; }
}
}
You can't, constants aren't virtual members.
What you could do instead is have a readonly property e.g
public class BaseClass
{
public BaseClass()
{
}
protected int MyProperty { get { return 10; } }
}
public class DerivedClass : BaseClass
{
public DerivedClass()
{
}
protected override int MyProperty { get { return 20; } }
}
I would like to only force the implementation of a C# getter on a given property from a base abstract class. Derived classes might, if they want, also provide a setter for that property for public use of the statically bound type.
Given the following abstract class:
public abstract class Base
{
public abstract int Property { get; }
}
If I want a derived class that also implements a setter, I could naively try:
public class Derived : Base
{
public override int Property
{
get { return field; }
set { field = value; } // Error : Nothing to override.
}
private int field;
}
But then I get a syntax error since I try to override the non existing setter. I tried some other way such as declaring the base setter private and such and I still stumble upon all kind of errors preventing me from doing that. There must be a way to do that as it doesn't break any base class contract.
Incidentaly, it can be done with interfaces, but I really need that default implementation.
I stumbled into that situation so often, I was wondering if there was a hidden C# syntax trick to do that, else I will just live with it and implement a manual SetProperty() method.
You can't do it directly, since you can't new and override with the same signature on the same type; there are two options - if you control the base class, add a second property:
public abstract class Base
{
public int Property { get { return PropertyImpl; } }
protected abstract int PropertyImpl {get;}
}
public class Derived : Base
{
public new int Property {get;set;}
protected override int PropertyImpl
{
get { return Property; }
}
}
Else you can introduce an extra level in the class hierarchy:
public abstract class Base
{
public abstract int Property { get; }
}
public abstract class SecondBase : Base
{
public sealed override int Property
{
get { return PropertyImpl; }
}
protected abstract int PropertyImpl { get; }
}
public class Derived : SecondBase
{
public new int Property { get; set; }
protected override int PropertyImpl
{
get { return Property; }
}
}
Would this suit your needs?
public abstract class TheBase
{
public int Value
{
get;
protected set;
}
}
public class TheDerived : TheBase
{
public new int Value
{
get { return base.Value; }
set { base.Value = value; }
}
}
The virtual was removed, but the base value is still the only storage for the value. So this should show '5'. And the compiler should fuss about b.Value = 4;
TheDerived d = new TheDerived();
d.Value = 5;
TheBase b = d;
//b.Value = 4; // uncomment for compiler error
cout << "b.Value == " << b.Value << endl;
-Jesse
What about something like:
public abstract class Base
{
public virtual int Property
{
get { return this.GetProperty(); }
set { }
}
protected abstract int GetProperty();
}
I had a similar requirement where I needed an interface to be able to share common sorting functionality between two loosely related classes. One of them had a read-only Order property and the other had a read-write Order property, but I needed a way to read the property the same way from both classes.
It turns out that this can be done by hiding the read-only value in a derived interface. Here is how I did it.
interface ISortable
{
int Order { get; }
}
interface ISortableClass2
: ISortable
{
// This hides the read-only member of ISortable but still satisfies the contract
new int Order { get; set; }
}
class SortableClass1
: ISortable
{
private readonly int order;
public SortableClass1(int order)
{
this.order = order;
}
#region ISortable Members
public int Order
{
get { return this.order; }
}
#endregion
}
class SortableClass2
: ISortableClass2
{
#region ISortableClass2 Members
public int Order { get; set; }
#endregion
}
class RunSorting
{
public static void Run()
{
// Test SortableClass1
var list1 = new List<SortableClass1>();
list1.Add(new SortableClass1(6));
list1.Add(new SortableClass1(1));
list1.Add(new SortableClass1(5));
list1.Add(new SortableClass1(2));
list1.Add(new SortableClass1(4));
list1.Add(new SortableClass1(3));
var sorted1 = SortObjects(list1);
foreach (var item in sorted1)
{
Console.WriteLine("SortableClass1 order " + item.Order);
}
// Test SortableClass2
var list2 = new List<SortableClass2>();
list2.Add(new SortableClass2() { Order = 6 });
list2.Add(new SortableClass2() { Order = 2 });
list2.Add(new SortableClass2() { Order = 5 });
list2.Add(new SortableClass2() { Order = 1 });
list2.Add(new SortableClass2() { Order = 4 });
list2.Add(new SortableClass2() { Order = 3 });
var sorted2 = SortObjects(list2);
foreach (var item in sorted2)
{
Console.WriteLine("SortableClass2 order " + item.Order);
}
}
private static IEnumerable<T> SortObjects<T>(IList<T> objectsToSort) where T : ISortable
{
if (objectsToSort.Any(x => x.Order != 0))
{
return objectsToSort.OrderBy(x => x.Order);
}
return objectsToSort;
}
}
You may do this with a constructor as following;
public abstract class Base
{
public abstract int Property { get; }
}
public class Derived : Base
{
public Derived(string Property) : base(Property)
{
}
}