MC++ Sample:
__gc __interface ICloneablePerson
{
Person* Clone();
};
public __abstract __gc class Person : public ICloneablePerson
{
private:
String* _name;
protected:
Person()
:_name(String::Empty)
{
}
Person(String* name)
:_name(name)
{
}
Person(Person* source)
:_name(source->_name)
{
}
public:
__property String* get_Name()
{
return _name;
}
};
public __gc class Student: public Person
{
private:
String* _id;
public:
Student(void)
:Person()
{
_id = String::Empty;
}
Student(String* name)
:Person(name)
{
_id = String::Empty;
}
Student(Student* source)
:Person(source)
{
this->_id = source->_id;
}
Student* Clone()
{
return new Student(this);
}
Person* ICloneablePerson::Clone()
{
return Clone();
}
};
public __gc class Test
{
public:
void static Start()
{
Person* person1 = new Student("David");
Student* person2 = new Student("Anthony");
Person* person3 = person1->Clone();
Student* person4 = person2->Clone();
}
};
However in C# .Net 2.0, I can't do that without explicitly casting.
C# Sample:
interface ICloneablePerson
{
Person Clone();
};
public abstract class Person:ICloneablePerson
{
string _name;
protected Person()
{
_name = string.Empty;
}
protected Person(string name)
{
_name = name;
}
protected Person(Person source)
{
_name = source._name;
}
public abstract Person Clone();
}
public class Student:Person, ICloneablePerson
{
string _id;
public Student()
:base()
{
_id = string.Empty;
}
public Student(string name)
: base(name)
{
_id = string.Empty;
}
public Student(Student source)
:base(source)
{
_id = source._id;
}
public override Person Clone()
{
return new Student(this);
}
Person ICloneablePerson.Clone()
{
return Clone();
}
}
public class Test
{
public static void Start()
{
Person person1 = new Student("David");
Student person2 = new Student("Anthony");
Person person3 = person1.Clone();
Student person4 = person2.Clone() as Student;
}
}
Is there a way to do the same like MC++ without an explicit casting.
Thank you.

Explicit Interface Methods Implementation
Dmytro Kryvko
If one wants a generic reference, try creating another interface which supersedes both person and student and return that instead.
William Bartholomew
Sounds like the advice I gave....
Lars E.Nes
Hi
How about this:
Now you can do this:
This is OK, too:
But this may raise some problem:
Yours Markku
Duckocide
using System;
using System.Collections.Generic;
using System.Text;
namespace SelfPractice.EIMI
{
interface ICloneablePerson
{
Person Clone();
};
public abstract class Person:ICloneablePerson
{
string _name;
protected Person()
{
_name = string.Empty;
}
protected Person(string name)
{
_name = name;
}
protected Person(Person source)
{
_name = source._name;
}
public Person Clone()
{
return ((ICloneablePerson)this).Clone();
}
}
public class Student:Person, ICloneablePerson
{
string _id;
public Student()
:base()
{
_id = string.Empty;
}
public Student(string name)
: base(name)
{
_id = string.Empty;
}
public Student(Student source)
:base(source)
{
_id = source._id;
}
public new Student Clone()
{
return new Student(this);
}
Person ICloneablePerson.Clone()
{
return Clone();
}
}
public class Test
{
public static void Start()
{
Person person1 = new Student("David");
Student person2 = new Student("Anthony");
Person person3 = person1.Clone();
Student person4 = person2.Clone();
}
}
}
z-one
It is not that simple.
Person has to be an abstract base class. Hence you can't instantiate the Person object.
Person implements an interface defines the "can" Clone() contract which returns the type of Person.
Student inherits from the Person class, and has to have a Clone() that returns the type of Student for type safety purpose.
Although, Functions differ only by its return type is not supported by C# and MC++, but MSIL supports it.
Although MC++ does not support this feature, but thru the use of EIMI (Explicit Interface Methods Implementation) this can still be done easily to offer greater reference polymorphism.
However in C#, I couldn't use the same trick again.
Xfolder
Look at the MC++ code, if the student object to be cloned is cast to a Student reference, it returns the cloned object with a Student reference. If the student object to be cloned is cast to a Person reference, it returns the cloned object with a Person reference without having to cast it explicitly.
I find it difficult to accomplish in C#, but MC++ does it easily.
xlthim
I don't think it is like your suggestion. Don't you see the difference
Based on the original question (there is already an interface), but you are suggesting creating another Interface (additional) that supersedes both classes.
However, the answer shown up there has no such additional Interface at all. It just cast this pointer into its Interface it implements at the base class and calls the clone() of that interface.
If there is no explicit implementation of the clone function at the child class, the whole algorithm is going to turn up like endless recursion.