✅ Issues with interfaces and generic classes
I want to create a general-practise chemistry model in C#. I have created some basic objects and created a few interfaces to specify the interactions between the classes. Now I have an issue when trying to create an instance with a generic class only allowing a certain interface.
I have attached a picture to make the relations a bit clearer. Now for the issue
Compound implements ISolute as well as IAmount
I now pack it into the Mol class which looks like this
Which works fine since compound implements it.
Now I want to create a solution out of it with this method of the solution class:
Where the problem arises of the ISolute interface not corresponding with the type Compound eventhough ISolute is implemented by Compound and inherits from IAmount
48 Replies
Also just for reference this is the corresponding unit test
This shows a pre compile error for both ISolute and ISolvent
I don’t see that compound implements Amount from ISolute
The chemist in me also suggests renaming “Concentration” to “Molality”?
i dont think i fully understand, but what if u create interface ICompound, implement IAmount and ISolute in it. use the new interface anywhere where u r having the compound. will this solve your problem?
The interfaces are empty as of now. Maybe I misunderstood you. Also yes. Renaming to molarity makes sense
Not sure but dont think so. Both ionized Elements and Compounds can be Solutes. Only compounds can be solvents. And both can be taken quantities of in Mol. That's why I thought I'd have the Mol generic as a wrapper around it which entails the quantity in addition to some IAmount of element or compound.
But extracting that to a new ICompound interface makes sense
This is the updated diagram
i really have no idea about chemistry, and even less so in english. so just inform me if that helps in any way. i wouldnt understand just by the diagram 😄
Also you're writing your tests in F#?
wait, this is f#? you can name functions with complex strings in f#? 😄
yea
Yes
XD
is that the only reason you're using F#...?
Nope. Just learned to love the language. Also less boilerplate because I already hate writing unit tests
makes sense
Oh do I see lambda calc in your bio?
ye I'm working on a lambda calc repl in Haskell for fun
Haven't used F# a ton but wanna try it out more tbh
Great to get work done quick. Kinda like python, although it has on par modeling ability with C#
Yeah can see that
Anyway sorry for diverting the thread
All good. Im working on a different part. Hoping a good idea pops up
Might add a github link too. Maybe it's beneficial to actually have others see the shit code I wrote
GitHub
GitHub - Jonathan-Schaefer-git/DotChem
Contribute to Jonathan-Schaefer-git/DotChem development by creating an account on GitHub.
Sorry, I misunderstood the Diagram. I read the IAmount as a property Amount. I’m can tell from the diagram alone why it wouldn’t resolve. Is there a specific compile error?
Nope. Sadly not. I honestly dont quite understand the error. It says that there is a type mismatch. I suspect it being the use of the Mol<IAmount> Wrapper class causing this
If you remove ISolvent from ICompound, does it work?
Just says Mol<Compound> is not compatible with Mol<ISolute> eventhough Compound implements both IAmount and ISolute
No. Same error
Maybe there is a way around this
Try to simplify it in another project with just IMol, ICompound, and IAmount? Add one interface at a time.
Ok sure. That makes sense 👍
Just says Mol<Compound> is not compatible with Mol<ISolute>bot Mol<> is not extending anything Mol<type1> is not compatible with Mol<type2> whatever the case they are two different types not even the generic type of Mol<> has a constraint
But ISolute inherits IAmount
bit Mol doesn't know it
Well shit. How would you correct for that?
maybe
class Mol<T> where T:ICompound
Was about to suggest this as well
yeah
although inheritance is not the easiest thing to deal with
Thing is though, that this isnt possible. It should be the IAmount interface as mol of elements are possible. So should I change it to IAmount? Wouldn't this have the same issue with interface inheritance as beforehand?
use whatever the base interface is
i put ICompound there but not with the entire knowledge of the project
ah ok i read the diagram in reverse
ok give me a minute
Yeah arrows are fucked up. It the VS designer thing
Ok. I believe I messed up, as it shows the same thing but with it now being broader the error changed
Is the header for the Mol class
But its now Mol<IAmount> is not compatible with Mol<ISolute>
Which means its still doesnt recognize the inheritance of the interface
This has the same error
because they still are two different types
you would have to make Mol inherit from something not generic
or use the same generic type
I... dont think I fully understand what you mean by that. Could you please elaborate or give me an example?
(basically it means
class Mol<IAmount> : IMol
, so that IMol m
could hold every Mol<>
, then you cast as needed; if you look at c# collections they have a common non-generic inheritance)
as Luxx said, i would just try starting with Mol with no generics, since at the moment it doesn't seem you need it
if you then need more, then you probably should read about covariance and contravariance
but i would try to stay as simple as possibleOk thanks
still, this should work
but it's kinda delicate and if you screw up it could throw exception at runtime
Yeah this would work. But I think I'll try the approach you described first
What tool did you use to create the diagram? Looks so neat
Visual Studio Class Designer. Its installable through the VS installer
just drag in a whole project and it auto generates it
I have implemented a simpler working version, although I'd like to pick up the Generic version tomorrow
Was this issue resolved? If so, run
/close
- otherwise I will mark this as stale and this post will be archived until there is new activity.Thanks to everyone @here. Thanks to your input I was able to figure it out 👍