I have two abstract types with a many to many relationship:
public abstract class Experiment<T> where T : Sample
{
private List<T> _Samples = new List<T>;
public IReadOnlyCollection<T> Samples {
get { return _Samples.AsReadOnly(); }
}
public void AddSample(T sample)
{
_Samples.Add(sample);
sample.Experiments.Add(this); // The problem lies here
}
}
public abstract class Sample
{
private List<Experiment<Sample>> _Experiments = new List<Experiment<Sample>>;
public ICollection<Experiment<Sample>> Experiments {
get { return _Experiments; }
}
}
As you can see, an experiment accepts a type parameter that is a subclass of Sample
. What I am trying to do is this: whenever an instance of a subtype of Sample
is added to an Experiment
, the Experiment
should correspondingly be added to the Experiments
collection of the Sample
.
The problem arises when I try to add an instance of an Experiment<T>
to a collection that is List<Experiment<Sample>>
. Since T
is a subtype of Sample
, I was assuming there wouldn't be a problem. What actually happens is the following:
Value of type 'Experiment<T>' cannot be converted to 'Experiment<Sample>`
My question is whether there is a way to work around this problem, or to better model the relationship between these entities.
public class Experiment<T> where T : Sample
{
private List<T> _Samples = new List<T>();
public IReadOnlyCollection<T> Samples
{
get { return _Samples.AsReadOnly(); }
}
public Experiment()
{
}
public Experiment(IEnumerable<T> samples)
{
_Samples = samples.ToList();
}
public void AddSample(T sample)
{
_Samples.Add(sample);
sample.Experiments.Add(new Experiment<Sample>(_Samples)); // The problem lies here
}
}
public abstract class Sample
{
private List<Experiment<Sample>> _Experiments = new List<Experiment<Sample>>();
public ICollection<Experiment<Sample>> Experiments
{
get { return _Experiments ; }
}
}
By adding some constructors and modifying the Experiments
collection in Sample
I think I was able to achieve what you're looking for. Now you can use the following code
public class MySample : Sample{}
public class MyExperiment : Experiment<MySample>{}
MyExperiment me = new MyExperiment();
me.AddSample(new MySample());
So I think the fix is this:
public abstract class Experiment<T> where T : Sample<T>
{
private List<T> _Samples;
public IReadOnlyCollection<T> Samples {
get { return _Samples.AsReadOnly(); }
}
public void AddSample(T sample)
{
_Samples.Add(sample);
sample.Experiments.Add(this); // The problem lies here
}
}
public abstract class Sample<T> where T : Sample<T>
{
private List<Experiment<T>> _Experiments;
public ICollection<Experiment<T>> Experiments {
get { return _Experiments; }
}
}
Because the two types are dependent on each other then they need to share the same generic type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.