C
C#2mo ago
Spiral Hero

Struggling with one thing about interfaces.

So, I watching a tutorial about IEnumerable and I realized I don't really understand how interfaces work. What I thought they were: Similar to classes as a level of abstraction, but they normally don't have any default method and instead just have all the methods that NEED to be implemented by their child classes instead. They also can't be instantiated as objects (but objects of classes that implement them can) However, I ran into an example close to this: EXAMPLE: List<MyClass> MyList = new List<MyClass> {...}; ImyInterface<MyClass> ModifiedList = MyList (Suppose that ImyInterface is an interface and that MyClass is a class that implements ImyInterface) Here, the interface name (alongside with the generic indicator <>) is put right before an object named ModifiedList. Which made me think that ModifiedList was an object of the class ImyInterface... What I don't understand is: First: That interfaces in theory were supposed to not have objects instantiated directly from them Second: Even if they could, what is the point of doing this instead of directly using MyList, if MyClass already implements all the ImyInterface methods... When I asked chat gpt (yeah, Im THAT desperate), it told me that actually ModifiedList is an variable of type ImyInterface, which is possible because variables are not the same as objects, and interfaces can't be objects but they can be variables. Now, I'm not sure if chat gpt is bullshitting me, so I was left unsure, since I was taught that variables were a simplified term, but are actually objects internally too. Which is why I was doubting the AI explanation. So, regarding the 2 questions I made above, what is the correct explanation? Sorry for the wall of text, I'm really confused.
35 Replies
Jimmacle
Jimmacle2mo ago
for once chatgpt isn't BSing you the reason interfaces exist is to allow code to use any kind of object as long as it implements certain methods for example, LINQ is built on IEnumerable which means it works with any collection type that implements that interface
Spiral Hero
Spiral Hero2mo ago
So, variables and objects are actually separate things?
Jimmacle
Jimmacle2mo ago
it's the same deal as an abstract class you can't instantiate it directly, but you can have objects that derive from it
Spiral Hero
Spiral Hero2mo ago
Im just confused because its typed in the same convention as a direct object instance like MyClass myInstance The class comes right before of the name of this instance. So it just looks like its doing the same
Jimmacle
Jimmacle2mo ago
that isn't an instance, it's just a variable (technically uninitialized) you don't create an instance until you do new MyClass()
Spiral Hero
Spiral Hero2mo ago
It seems i really dont understand a thing then 😂😂 I thought any object or variable was an instance.
Jimmacle
Jimmacle2mo ago
as far as classes are concerned, variables hold references to instances of objects kind of like pointers in C++ if you've learned that
Spiral Hero
Spiral Hero2mo ago
uhh i learned C so i kinda know about pointers (long time ago) Does a variable that isnt an instance (no new() after) does anything in practice?
Jimmacle
Jimmacle2mo ago
it's uninitialized, and you can't use it until you've assigned a value to it or you'll get an error when you do something like ImyInterface<MyClass> ModifiedList = MyList the actual object is still a List<MyClass> but you can only access the members defined by ImyInterface<MyClass> through the variable
Spiral Hero
Spiral Hero2mo ago
Its an empty variable, but what does saying it belongs to an interface do?
Jimmacle
Jimmacle2mo ago
i wouldn't say that, it doesn't make sense variables have data types which define what values they're allowed to hold if your variable is an IMyThingy then it can hold a reference to any object that implements the IMyThingy interface
Spiral Hero
Spiral Hero2mo ago
So you are forcing the variable's future instance to be from a class that implements that interface? is that it?
Jimmacle
Jimmacle2mo ago
you could say that
Spiral Hero
Spiral Hero2mo ago
hmm
Jimmacle
Jimmacle2mo ago
it's the same reason you can't say int myNumber = "a string", the types aren't compatible because a string is not an int but when you're dealing with classes and inheritance, a variable can hold objects derived from its defined data type in addition to that data type itself
Spiral Hero
Spiral Hero2mo ago
So you are saying: This variable holds any, but only, types/classes that implement this Interface would that be correct?
Jimmacle
Jimmacle2mo ago
exactly
Spiral Hero
Spiral Hero2mo ago
Hmmmmmmm yeah im starting to grasp
Jimmacle
Jimmacle2mo ago
the reason you can do it is because derived types still have the same original "shape" as their parent class/interface so they can do everything the parent can do, so they fit into the variable they might have extra stuff but that's fine, because they still have the stuff needed to "be" that parent type
Spiral Hero
Spiral Hero2mo ago
In a way, would be correct to say we dont refer to instances directly, but we reference and point them via variables in reality?
Jimmacle
Jimmacle2mo ago
for classes (reference types in general) yes, the variable never actually holds the data of the object the object lives somewhere else and the variable just tells you how to find it brb
Spiral Hero
Spiral Hero2mo ago
Last thing, if I'm doing: ImyInterface<MyClass> ModifiedList = MyList (in which MyList was a List<MyClass> itself) Why wouldn't I just directly use the variable MyList? Why would I need to make a variable of any type that implements ImyInterface, and then proceed to define which one it is? Couldnt I just directly use MyList for whatever I do? No hurry Maybe so you can change in other point of the code where does that variable "points to", like another instance of another type (but, that also implements that interface) Because if it was MyList, I wouldn't be able to change the variable to another instance of another type? Just my theory idk if it makes any sense.
Kouhai
Kouhai2mo ago
ImyInterface<MyClass> ModifiedList = MyList Assuming List somehow implements ImyInterface You typically wouldn't just use it like that but instead Given a function void MyFunc(ImyInterface<MyClass> classList) You can pass MyFunc(MyList) But also beacuse the method takes n generic interface ImyInterface<MyClass> you can pass any class that implements said interfaces not just List<MyClass>
Spiral Hero
Spiral Hero2mo ago
Sorry If i misunderstood what you said, but are you saying something close to what I said here? : .
Kouhai
Kouhai2mo ago
No it's different Let's take another example interface IAnimal That interfaces has a method void Behaviour() And we have 3 classes, cat, dog, rabbit Let's say we also have a method that calls that method in the animal so for example void SimulateAnimal(Cat cat) void SimulateAnimal(Dog dog) void SimulateAnimal(Rabbit rabbit) As you can see we have 3 duplicates even though it makes sense to have one So intead we could do void SimulateAnimal(IAnimal animal) We could then pass a cat, dog or rabbit to that method
Spiral Hero
Spiral Hero2mo ago
(please keep going ill just brb real quick)
Kouhai
Kouhai2mo ago
This makes your code way more maintainable Another example let's say you need to log something And you don't really concern yourself where these logs are saved, maybe written to a console, or saved to file In this case it would make more sense to take an ILogger instead of ConsoleLogger and FileLogger
Spiral Hero
Spiral Hero2mo ago
Yeah that makes a lot of sense Thanks guys, you are all super smart and helpful. 🙏🙏 (Idk If I can still ask about it in the same thread) What about methods with interface type before it? Does that mean the return type can only be a class that inherits from that interface, otherwise it sends an error? example: ImyInterface<T> CoolMethod() { ...
Jimmacle
Jimmacle2mo ago
yes, this is general OOP if the return type is IMyInterface<T> then whatever value is returned must implement IMyInterface<T>
Spiral Hero
Spiral Hero2mo ago
then you use an exception catch thingy to let the caller know if its not? otherwise wouldnt it crash? probably yeah im just new to programming in general :Kek:
Jimmacle
Jimmacle2mo ago
no, because you'll never run code that breaks this rule it's a compiler error the compiler knows what has to be returned and what you're returning, and if it won't work it won't compile
Spiral Hero
Spiral Hero2mo ago
what if the inner working of the method changes with user input and therefore can be or not be the correct type on the return depending on circumstances? does the compiler still not run it just bcs of the possibility?
Jimmacle
Jimmacle2mo ago
like i said, that code would be invalid
Spiral Hero
Spiral Hero2mo ago
i see, thank you
Jimmacle
Jimmacle2mo ago
it must always return a compatible type or it won't compile
Want results from more Discord servers?
Add your server
More Posts
Help with librariesHey, I just " coded " this c++ code using chatgpt and I need a little bit of help, I need help with Trying to use Electron.NET with Blazor Web AppWhen I tried creating a ``Blazor Web App`` and implementing [Electron.NET](https://github.com/Electr.net ecosystem questionsI am a bit confused on what is .net and it's ecosystem. From my understand and please correct me ifASP.NET: Elegant controller <-> service interactionHey! I am looking for an elegant controller <-> service interaction. Example (pseudocode): ```cs [ACan't figure out how to apply attributes to values in json property dictionary (System.Text.Json)This is my model that I'm working with ```csharp //TODO convert to DateTime [JsonPropertyName("peacRecommendation for handling logging in a APIHello Hello. Im fairly new in the DOTNET world so im not familiar with all the libs. I want to use Reading config files (mostly secrets) from outside appsettings and env vars - bad idea?Looking for best practices / existing features to avoid reinventing the wheel (more than we have). asp - Calling another api endpointHey, i have a stream containing a raw request and would like to call the asp.net core request pipeliTesting practices and librariesI'm just starting with testing, I'm not that much of a fan, most of the time for me it wasn't neededSwitching to C# and curious if there's anything I could improve on in this very basic math script.```c# class Program { static void Main() { MathClass.Print(2,5,"subtract"); } }