List with different types - c#

I'm new at the C# thing.... (.net 3.5)
I want a Dictionary to hold two different types of object, one of the type is generic. while iterating through the list, i will call methods like add and clone.
I have tried it with a base class and subclasses....
namespace ConsoleApplication1 {
class Element{
}
class Child1 : Element {
public Child1 Clone() { return clone; }
}
class Child2<T> : Element {
public Child2<T> Clone() { return clone; }
}
class Program {
static void Main(string[] args) {
Dictionary<string, Element> d = new Dictionary<string, Element>();
d.Add("c1", new Child1());
d.Add("c2s", new Child2<string>());
d.Add("c2i", new Child2<int>());
foreach (KeyValuePair<string, Element> kvp in d) {
Element e = kvp.Value.Clone();
}
}
}
}
Is there a way or solution for my needs?
Thanks!
Anna

You could make Clone either abstract or virtual on the base-type (Element), and override it in the derived types, but you can't change the return type when overriding, so it would have to be Element (nothing more specific). You can redeclare methods (new...), but that gets messy, and you can't override and new a method by the same name/signature in the same type.
But if you're happy for the return type to be Element...
abstract class Element{
public abstract Element Clone();
}
class Child1 : Element {
public override Element Clone() { return /* your code */; }
}
class Child2<T> : Element {
public override Element Clone() { return /* your code */; }
}

Since the type of .Value you get out of your dictionary is Element, you need to make sure Element defines all operations it should have, like your Clone method.
I would:
Make Clone virtual, and add it to Element (or make Element abstract, and Clone abstract instead of virtual)
Override Clone in both Child1 and Child2
This way, the code kvp.Value.Clone() would call the right Clone method depending on the object returned from the dictionary.

Don't create a class hierarchy just for the sake of being able to add different objects to one dictionary though.
If the classes don't have a decent enough hierarchical relationship, you would be better off using an interface like ICloneable, which is already available in the .NET framework.
Then, simply instantiate your Dictionary like:
Dictionary<string, ICloneable> d = new Dictionary<string, ICloneable>();
It's more flexible. Creating a hierarchy for the sake of the commonality of being able to perform Clone(), is not the right solution IMO.

Though I agree with Wim, that implementing ICloneable is probably the better solution, rather than trying to enforce a non-existing class hierachy, please be aware that ICloneable is considered a "bad API" as it does not specify whether it uses shallow- or deepcopy semantics (see for instance http://pro-thoughts.blogspot.com/2009/02/write-deep-clone-forget-about.html or do a google search for "ICloneable C# bad API"

Related

Creating an abstract generic method

I have a C# class with a method such as below:
public class MyType
{
public MyType Clone()
{
var clone = (MyType)MemberwiseClone();
// Do some other stuff here with the clone's properties
return clone;
}
}
I have a bunch of other classes where I want to implement the Clone method so I was thinking I could create an abstract base class where I could define the Clone method generically so I don't have to put a concrete implementation in each class.
I would think this is possible but I haven't worked too much with generics and my attempts to do this in the past (months ago, so discarded my code out of frustration) haven't been successful.
Is this possible? If so, how could it be done?
Create an abstract generic base and then implement the concrete type on the derived ones:
public abstract class ClonableBase<T>
{
public T Clone()
{
return (T)this.MemberwiseClone();
}
}
public class RealClass : ClonableBase<RealClass> { }
The usefulness of this approach depends significantly on what it is that you're cloning.
Here's a method that I use. The cloning method is a bit crude. It's specifically for objects that are meant to be serialized as JSON.
That's why the generic constraint (TEntity : BaseEntity) is there. I don't want just anything passed into this method, only something that I know is serializable.
I also avoided using the generic argument for JsonConvert.DeserializeObject because while I want to cast the result as a specific type, I don't want to pass in an inherited type and get back an instance of a base type.
public static TEntity CloneEntity<TEntity>(this BaseEntity input) where TEntity
: BaseEntity
{
if (input == null) return null;
var serialized = JsonConvert.SerializeObject(input);
return (TEntity)JsonConvert.DeserializeObject(serialized, input.GetType());
}
Although it's already been accepted, I don't recommend adding this to a base class unless absolutely necessary. Before long you might find that you need to clone something that already inherits from a different base class.
This requires the Newtonsoft.JSON package.
As mentioned in a comment, this will do a deep clone. As I stated at the top, this method applies only if serialization/deserialization cloning is appropriate to the types you need to clone. If there were a universally applicable way to clone objects that applied in every case then object would probably have a public Clone method.
If we're cloning classes it's likely because they contain data, and where that's the case deep cloning is likely preferable. For example, suppose we have a Customer class, and one if its properties exposes an Address object. MemberwiseClone will clone the value types, but will result in two Customer objects that share a reference to the same Address. If we're cloning it's usually because we're trying to create entirely distinct objects. If we think we've cloned something but beneath the surface the original and clone share object references then there's a good chance we'll have bugs.
Built on #Gusman's solution I add the possibility to do some initialization
public abstract class ClonableBase<T>
{
public T Clone()
{
T clone = (T)MemberwiseClone();
Initialize(clone)
return clone;
}
protected virtual void Initialize(T clone)
{
}
}
If the initialization is mandatory, you can also make Initialize abstract instead.
public class RealClass : ClonableBase<RealClass> {
protected override void Initialize(T clone)
{
// Do some other stuff here with the clone's properties
}
}

in c# for type safe tree implementation (typesafe node)

I am looking for /tring to implement a type safe tree implementation in C#.
How can a type safe tree be implemented, without using interfaces (which force to reimplement the tree functionality all over the place) and without using casts?
I have the idea of using tree as common base class, but then type safety is gone. My current approach is usage generics. But I am missing some conversion back to the base type.
Below is a reduced/nonworking example.
The idea is that the returned Nodes support the tree functions, and at the same time they also support their base types behaviour.
I could use the below class without and inherit from Node, but then then I loose type safety on one hand, and also get problems with inheritance, as the Nodes have already parent classes.
I also toyed with class extensions, but I haven't got anything that is close to a possible solution.
I think i need one small hint on how to continue. Thank you in Advance.
public class Node<T> // .
{
public Node<T> parent;
public List<Node<T>> children;
protected Node()
{
children = new List<Node<T>>();
parent = null;
}
protected Node(Node<T> parent)
: this()
{
this.parent = parent;
parent.addChildren(this);
}
protected void addChildren(Node<T> child)
{
children.Add(child);
}
public Node<T> getRoot() // returns root node
public List<Node<T>> flatten() // return 1d-list of all nodes.
}
Here's a type-safe tree implementation:
public class Tree<T> : List<Tree<T>>
{
public T Value { get; set; }
}
Yes, that's it. Simple.
Of course, you could add a constructor or two, and make the Value property read-only to make it a little more OOP friendly. And you could easily add the Parent property.
I have the idea of using tree as common base class, but then type safety is gone. My current approach is usage generics. But I am missing some conversion back to the base type.
Then constraint the generic type to your base type:
public class Node<T> where T: BaseType { ... }
Now you can create any tree of the type Node<MyDerivedType> as long as MyDerivedType derives from BaseType.
On a side not, I'd consider modifying the following in your implementation:
Children should be a property, do not expose a field unless its readonly. Furthermore, you should not expose it as a List; that would let anyone add or remove nodes directly which can violate invariants assumed in your implementation. Return an IEnumerable<T> instead:
private readonly List<T> children;
public IEnumerable<T> Children => children.Select(c => c);
You could return children directly as its implicitly convertible to IEnumerable<T>; the problem is that anyone can simply cast it back to List<T> and modify it. Projecting it protects you from this conversion.
Same happens with Flatten (the first f should be capitalized btw). Consider returning an IEnumerable<T> too.

How to create a strongly typed collection that only contains one element per type

I'm in the process of trying to create a collection that will only contain one element per type. Each of the types will have to subclass a root type however, so that there is a commonality.
I've done some research and am wondering if I'm on the right track here or if there are some improvements that can be made:
class TypedList<T> : Dictionary<Type, T> {
public override void Add<C>(T instanceOfType) {
base.Add(typeof(C), instanceOfType);
}
}
Specific questions:
Is this the correct/best approach?
What should I do to facilitate retrieving elements?
If the Add() method is correct, is there any way to enforce that C is a subclass of T?
Updated code to reflect Ondrej's suggestions:
class TypedList<Abstract> : IList<Abstract> {
protected Dictionary<Type, Abstract> data;
public void TypedList() {
data = new Dictionary<Type, Abstract>();
}
public void Add<Concrete>(Concrete instanceOfType) where Concrete : Abstract {
data.Add(typeof(Concrete), instanceOfType);
}
}
Many months later and I think I've come up with a really nice solution, which is to use a collection I wasn't aware of initially KeyedCollection:
public class TypedSet<AbstractType> : KeyedCollection<Type, AbstractType> {
protected override Type GetKeyForItem(AbstractType item) {
return item.GetType();
}
}
Very conscice and doesn't require any stitching of different types of collection classes together. Makes for slightly more idiomatic code as well as KeyedCollection is abstract and requires implementation of GetKeyForItem.
This should give you the constraint you're looking for!
class TypedList : Dictionary {
public override void Add<C>(T instanceOfType) where C : T{
base.Add(typeof(C), instanceOfType);
}
}
However, I'm wondering why you're not just using a dictionary straight up?
I.E. the dictionary that you're subclassing should behave the way you waint?
The approach generally seems fine. However, I'd consider hiding the Dictionary<Type, T> as a private field and reimplementing the interface you want. It needs not to be IDictionary<Type, T>, it may as well be just a IList<T>.
Another option is to use List<T> for internal storage, and HashSet<Type> to maintain the set of types of items in the list. Such underlying storage may be better suited in case IList<T> is the wanted interface of TypedList<T>, solving the “missing index” problem with a dictionary.
Also, the Add<C> method declaration seems incorrect. You should declare it as:
public override void Add<C>(C instanceOfType) where C : T {
base.Add(typeof(C), instanceOfType);
}
That makes sure C will be an ancestor of T. In your original declaration C could have been any type, possibly unrelated to T.

What is use of Parent object instantiating with child class

Please tell me what is of parent object instantiating with child class like:
public class A
{
public A()
{
Console.WriteLine("A");
}
public virtual void method()
{
Console.WriteLine("AM");
}
}
public class B : A
{
public B()
{
Console.WriteLine("B");
}
public new void method()
{
Console.WriteLine("BM");
}
public void method1()
{
Console.WriteLine("BM1");
}
}
class Program
{
static void Main(string[] args)
{
A obj = new B();// what is use of it?
obj.method();
Console.Read();
}
private void methodP1()
{
}
}
please tell me what is use of
Parent obj = new Child();
as i we can only call to only public methods of parent class which is possible using
Parent obj = new Parent();
is it possible: Child obj = new Parent() ?
please tell me what is use of Parent
obj = new Child(); as i we can only
call to only public methods of parent
class which is possible using Parent
obj = new Parent();
This is the basis for polymorphism: Imagine you have several child classes that inherit from you parent class. You want to use all these child classes through the interface / methods defined on your parent class, without worrying about the implementation details in each child class (each might do something different, but with the same overall semantics).
This is possible because the child class has a IS A relationship with its parent class since child inherits from parent.
In your example, B is-a A, but A is-not-a B.
The above is of use when the code using the reference to B can only understand (or needs to understand) types of A. B is a specialisation of A. Imagine something like (pseudo-code)
Shape s;
if (x == 1) {
s = new Square();
}
else {
s = new Triangle();
}
// following code knows only about Shapes
s.draw();
s.calculateArea();
The following code doesn't need to know if s is a square or a triangle, just that it's a shape. What use is that ? If you call s.draw(), the shape itself determines how it's going to look. The code calling it doesn't know or care.
This is a key point of object-oriented programming. Asking objects to do things for you rather than determine yourself what's needed.
Note that your final question doesn't intuitively make sense when using this example.
Shape s = new Square(); // fine
vs
Square s = new Shape(); // can you instantiate a "shape" and why then do you decide it's a square?
BrokenGlass's answer is correct. However, your sample will have different behaviour depending upon whether you declare obj as type A or B.
In the case of A obj = new B(); the program will output A B AM because the compiler is linking to the virtual method A.method, which class B then inherits.
In the case of B obj = new B(); the program outputs A B BM because the compiler is directed to use the new method B.method().
If B.method() was instead declared as public override void method(), then the output would always be A B BM regardless of whether obj was declared as type A or type B.
Thus your example does not show polymorphism in the classic sense, as the method called on instances of type B depends on the type of the variable to which the instance is assigned. This can make debugging fun and interesting.
The reason that you would use polymorphism is so that you can pass a more specific object to an entity that only requires a more general object. The entity that receives the object only cares about the public interface that is exposed, not the details of how the methods in that interface are carried out. Here's a simple class hierarchy:
public class Animal
{
public virtual string GetFood()
{
return "Food";
}
}
public class Monkey : Animal
{
public override string GetFood()
{
return "Bananas";
}
}
public class Cow : Animal
{
public override string GetFood()
{
return "Grass";
}
}
And here's how you could use the polymorphism:
class Program
{
static void Main(string[] args)
{
Animal[] animalArray = { new Monkey(), new Cow() };
foreach (Animal a in animalArray) {
WhatDoIEat(a); // Prints "Bananas", then "Grass"
}
}
static void WhatDoIEat(Animal a)
{
Console.WriteLine(a.GetFood());
}
}
If you have to use only the methods on the parent class, you can go ahead and instantiate it. The object of a child class is to add functionality to the parent class while keeping the parent intact. Instantiating the parent through the child without further use of the child functionality does not make sense.
There's no use in simple examples like yours, where the scope of usage for the variable is limited. But it's important to understand that in .NET variables has types that are static, known at compile time and even if obj keeps a reference to Child class, it is still typed as Parent.
And when you have method that requires Parent, you can pass obj (with type Child) to it (and it still behaves like Child) - this is an example of Child being referred by Parent type.
Child obj = new Parent() is not possible, Parent is not a Child, compiler wouldn't let you assign object to variable of incompatible type.
Say you have a parent class called Animal and child classes called Dog, Cat, and Lizard. Each class has a method call makeSound(). Then when you say Animal a1 = new Dog(); and Animal a2 = new Cat(), a1.makeSound() will bark and a2.makeSound() will meow.
The technical term for this behavior is called polymorphism. It is useful for code reuse. You only need to write code once for an application that has Animals makeSound() when they are happy, instead of separate code for each animal type.
Another use of polymorphism is hiding your code's implementation from other users. For example you can show other users that you are using a List and then you have the choice to implement the List as a LinkedList or as an ArrayList. You can also choose a LinkedList and then at a later time switch to an ArrayList without effecting your users.
You also can't say Dog d = new Animal() because a Dog is an Animal but an Animal is not necessarily a Dog.
When You Know Common features about a Class which inherits from and when you dont know the exact child you can put the data on Parent class, whenever you knew about the child class you can assign those values on it.

Copying objects to 'this' object in C#

I have a certain hirerchy of classes that needs the capeability to copy all public properties from one object to another.
Each class has a certain set of public properties that might differ from any other class.
Example:
class Base
{
// Common properties/methods...
public void Copy<T>(T data) where T : Base
{
// ...
}
}
class D1 : Base
{
public int ID
{
get;
set;
}
}
class D2 : Base
{
public string Name
{
get;
set;
}
}
Through googling I have read about those methods:
Using reflection
Generating IL code
Serialization
All of them are either very complex or very slow or sometimes both.
Am I missing something? Is there any other way to access the raw this pointer?
EDIT:
I will clerify.
T is of the type of the calling class. For example if it was called by D1 T will always be D1.
The reason for the generic is that I can't really know what T is.
Am I missing something?
Should I just use Base data as the parameter?
What you're missing is that you're asking the compiler to know that T might be one of the types D1 and D2 when all you've said is that T is a Base. How could it possible know what properties or even type your object is as that information is only known at runtime. Even if you could go foreach (PropertyInfo in this.Properties) it's going to find out the name of those properties at runtime so be just as slow as Reflection because how else can it? (it is reflection, just prettier syntax). It can't know what properties are common until it knows what types it's dealing with and you've said "i'm not telling you until runtime" so the answer is "well I'll have to look at runtime" i.e. reflection.
Secondly, just because D1 and D2 might both have a property named Size doesn't mean they are the same property (unless that property is present in a common ancestor).
For example,
ArtilleryAmmo.Shell and
PecanNut.Shell.
AcmeCorp.Staff and GandolfTheWizard.Staff
California.State and MyBrokenEngine.State
LoudSpeaker.Volume and MassiveCrater.Volume
Cave.Bats and BasketballGame.Bats
etc. etc.
You could work around this using an architectural change and use a 'PropertyBag' to store each class' properties.
A PropertyBag is essentially a Dictionary<string, object> where you can give a piece of data a name and add it to the bag. The disadvantage is that everything gets cast to object, so it isn't very type safe plus there's lots of boxing/unboxing, plus the strings as names don't get checked at compile time, so typos are a constant threat.
When you define a property on the class, you store/retrieve the item from the class' propertybag:
public int MyProperty
{
get
{
return (int)_propertyBag["MyProperty"];
}
set
{
if(_propertyBag.Keys.Contains("MyProperty"))
{
_propertyBag["MyProperty"] = value;
}
else
{
_propertyBag.Add("MyProperty", value);
}
}
}
So now to aggregate all the properties of the derived classes, you can expose their 'raw' PropertyBag and iterate through it.
Like I said before, the PropertyBags aren't type-safe, so it you have two classes in the hierarchy with the same property name but different type then you're getting into trouble.
EDIT: If you're concerned with performance, you're going to have to implement this multiple ways and perf test the different implementations -- I can't honestly say if a PropertyBag will actually be faster than using reflection.
The Copy method in the Base class only has access to the properties that are defined in the Base class. You can copy these properties.
But you cannot copy the properties from the subclasses without using something like reflection. But even with reflection you need some kind of knowledge about the mapping of the properties between different subclasses, like copying the ID property to Name.
So you'll need to write separate implementations for each (allowed) subclass conversion.
public interface IBaseCopier<TFrom, TTo> where TFrom : Base, TTo : Base
{
void Copy(TFrom from, TTo to);
}
public class D1ToD2Copier : IBaseCopier<D1, D2>
{
public void Copy(D1 from, D2 to)
{
// Copy properties from the D1 instance to the D2 instance.
}
}
You can register all the ICopier<TFrom, TTo> implementations in a factory class. This class will look up the implementation of the copier, based on the type arguments. If there is no copier for a certain type combination, i.e. the conversion is not supported, the factory should throw an exception.
public class CopierFactory
{
public ICopier<TFrom, TTo> Create<TFrom, TTo>() where TFrom : Base, TTo : Base
{
// Look up the ICopier implementation for the given types.
}
}
Edit
You can use the MemberwiseClone method to create a copy of an object.
public class Base
{
public static T Copy<T>(T data) where T : Base
{
return data.MemberwiseClone() as T;
}
}
If you need more control over the cloning, you can implement the ICloneable interface.
Note: You should realize that you cannot clone a D1 instance into a D2 instance. That would be like cloning a sheep into a horse.
I think the copy method should be inherited by derived classes D1,D2 and their responsibility to copy their own properties to/from other types.
What I would do is create an extension method for the Base class like:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static int CopyTo<T>(this Base source, ref T dest)
{
// Use reflection to cycle public properties and if you find equally named ones, copy them.
}
}
}
Then you could call it in your objects and like:
source.CopyTo<ClassType>(ref this);
I didn't test, so not sure if it would work exactly like described. I did something similar to Cast DataRows into Entities in a big project I worked on.

Categories

Resources