Link to home
Start Free TrialLog in
Avatar of ITsolutionWizard
ITsolutionWizardFlag for United States of America

asked on

c# interface

Alert error pointing to void Add() inside of the interface
why? and how to fix it?

error message:  Surety.Repository.PrincipalRepository does not implement interface member 'surety.repository.Itest.Add()



namespace Surety.Repository
{

    interface Itest
    {
        void Add();
    }

    #region members
    public class PrincipalRepository: Itest
    {
        public void Add(Principal principal)
        {
            using (var ctx = new Context())
            {
                Principal newPrincipal = new Principal() {  PrincipalName = principal.PrincipalName };
                ctx.Principals.Add(newPrincipal);            
                ctx.SaveChanges();
            }
         }
    }
    #endregion

}
ASKER CERTIFIED SOLUTION
Avatar of Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger)
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of ITsolutionWizard

ASKER

Please show me in codes
SOLUTION
Avatar of AndyAinscow
AndyAinscow
Flag of Switzerland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Vel Eous
Vel Eous

You can think of an interface as a contract or an abstract base class, it defines behaviour which all classes that inherit from the interface must implement exactly as defined by the interface.

public interface IAnimal
{
    void Feed();
    void GiveName(string name);
}

public class Dog : IAnimal
{
    public void Feed()
    {
        ...
    }

    public void GiveName(string name)
    {
        ...
    }
}

public class Cat : IAnimal
{
    public void Feed()
    {
        ...
    }

    public void GiveName(string name)
    {
        ...
    }
}

Open in new window


The IAnimal interface defines only methods in this example, however, you can define events or properties too.  It defines behaviour which is common to all the classes which inherit from it, in this example all animals should have the ability to be fed and given a name.  There are many benefits to this, however, a simple example is that methods or classes that depend on an object which inherits from IAnimal do not need to know which concrete type they are working with, only that it behaves the same as any other object type that inherts from IAnimal.

As mentioned the inheriting classes must provide an exact implementation of the interface they inherit, there can be no alteration to the signature.  So if a method is defined in the interface as

void Add(IPrincipal principal);

Open in new window


It must be implemented as such in your inheriting object(s), failure to do so with cause a compiler error such as "Interface member '...' is not implemented"
I have below codes and using interface.cs as interface class and got same error message.
so the question is

1. why?
2. Can one interface collects two voids from two different class? Now I got error alert.

My goal is using 1 intereface to collect all other classes. And on aspx file I can just use interface.



 From principal.cs
 public class PrincipalRepository:IBondQuote
    {
        public void AddPrincipal(Principal principal)
        {
            using (var ctx = new Context())
            {
                Principal newPrincipal = new Principal() {  PrincipalName = principal.PrincipalName };
                ctx.Principals.Add(newPrincipal);            
                ctx.SaveChanges();
            }
          }        
    }


  From Indemnitor.cs
  public class IndemnitorRepository
    {
        public void AddIndemnitor(Indemnitor indemnitor)
        {
            using (var ctx = new Context())
            {
                Indemnitor newIndemnitor = new Indemnitor() { FirstName = indemnitor.FirstName, LastName = indemnitor.LastName, MiddleName = indemnitor.MiddleName };
                ctx.Indemnitors.Add(newIndemnitor);
                ctx.SaveChanges();
            }            
        }
    }


From Interface.cs
 public interface IBondQuote
    {
        void AddPrincipal(Principal principal);
        void AddIndemnitor(Indemnitor indemnitor);
    }
>>and got same error message.
That I doubt.  An error message - yes, the same - no.

You would get an error message about one function NOT being implemented.  You have to implement each of the methods declared in the interface.  So anything based on IBondQuote has to implement both AddPrincipal and AddIndemnitor.

>>My goal is using 1 intereface to collect all other classes.
You can do, but I suspect is a very bad idea.  You really want multiple interfaces.  Remember a class can be based on more than one interface

eg.
public class X : IFirst, ISecond, Ithird
>>and got same error message.
I've just realised that your use of same was not what I thought it was.  You would get the same error being flagged but for a different method in the interface.
The reason you're getting the same error message again, is because your interface defines two methods:

public interface IBondQuote
{
    void AddPrincipal(Principal principal);
    void AddIndemnitor(Indemnitor indemnitor); 
}

Open in new window


Yet when you inherit from the interface on your classes:

public class PrincipalRepository : IBondQuote

Open in new window

 // Note that you've not actually inherited the interface here
public class IndemnitorRepository

Open in new window


You only implement one of the methods in the interface.  An interface is a contract, it enforces that any objects which inherit from the interface will and must provide implementations of the behaviour defined in the interface.

Take a look at the following which I posted previously:

public interface IAnimal
{
    void Feed();
    void GiveName(string name);
}

public class Dog : IAnimal
{
    public void Feed()
    {
        ...
    }

    public void GiveName(string name)
    {
        ...
    }
}

public class Cat : IAnimal
{
    public void Feed()
    {
        ...
    }

    public void GiveName(string name)
    {
        ...
    }
}

Open in new window


IAnimal is the interface, it defines two methods: void Feed() and void GiveName(string name).  The objects Dog and Cat inherit from IAnimal and are therefore bound by this interface contract to provide an implementation for both of the methods.  Failure to provide implementation results in a compiler error (as you are describing).

So what you need to do is provide implementations of each method defined in your interface on each of the inheriting classes:

public class PrincipalRepository : IBondQuote
{
         void AddPrincipal(Principal principal)
         {
                  throw new NotImplementedException();
         }
         void AddIndemnitor(Indemnitor indemnitor);
         {
                  throw new NotImplementedException();
         }
}

public class IndemnitorRepository : IBondQuote
{
         void AddPrincipal(Principal principal)
         {
                  throw new NotImplementedException();
         }
         void AddIndemnitor(Indemnitor indemnitor);
         {
                  throw new NotImplementedException();
         }
}

Open in new window


Obviously you would provide actual implementation and not just throw an exception, but I skipped that for brevity.

If you do not require your Repository classes to implement both interface methods, then you shouldn't be using an interface as you are.

You could do something like the following, however, it may or may not be appropriate for your scenario.  It is merely an example.

namespace EE
{
    using System.Security.Principal;

    public interface IRepository<T> where T : class
    {
        void Add(T item);
    }

    public class PrincipalRepository : IRepository<IPrincipal>
    {
        public void Add(IPrincipal principal)
        {
            using (var ctx = new Context())
            {
                var newPrincipal = new Principal {PrincipalName = principal.PrincipalName};
                ctx.Principals.Add(newPrincipal);
                ctx.SaveChanges();
            }
        }
    }

    public class IndemnitorRepository : IRepository<Indemnitor>
    {
        public void Add(Indemnitor indemnitor)
        {
            using (var ctx = new Context())
            {
                var newIndemnitor = new Indemnitor
                {
                    FirstName = indemnitor.FirstName,
                    LastName = indemnitor.LastName,
                    MiddleName = indemnitor.MiddleName
                };
                ctx.Indemnitors.Add(newIndemnitor);
                ctx.SaveChanges();
            }
        }
    }
}

Open in new window

The last one is fine to me. Can you tell me more about the last one? I want to learn the logics.
The last one is fine to me. Can you tell me more about the last one? I want to learn the logics.

Your original interface defined two methods:

public interface IBondQuote
{
    void AddPrincipal(Principal principal);
    void AddIndemnitor(Indemnitor indemnitor); 
}

Open in new window


The concept shared between these two methods is the concept of performing an Add, you're defining methods which will Add either a Principal or an Indemnitor.  Whilst the concept of adding one of these objects is the same, the implementation differs.

So we know there is a common concept.  We want to add an object, but unfortunately the add implementations differ for each object so we could define specific interfaces for each object like so:

public interface IPrincipalRepository
{
    void Add(IPrincipal principal);
}

public interface IIndemnitorRepository
{
    void Add(IIndemnitor indemnitor);
}

Open in new window


The above is perfectly acceptable, its function is explicit and understandable.  With this being a repository example it is not unthinkable that you would want to add other methods to perform other CRUD operations (read, update, delete) on both the interfaces.  Whilst not a massive problem in this trivial example, you are repeating yourself writing methods in each interface to achieve the same goal on different objects.  Wouldn't it be great if we could abstract this further to have one interface for both objects?

In C# 2.0 Generics were added to the language providing increased flexibility and power (amongst other things).  We can leverage generics in this scenario to achieve exactly what we did above with two explicit interface definitions, with a single interface definition and still maintain strong type checking (thanks to the compiler).

So now we can do

public IRepository<T>
{
    void Add(T item);
}

Open in new window


Viola, a generic repository where we can substitute T for anything we choose and the compiler will ensure that our Repository can only be used with the substituted type and we only have to maintain the one interface.  That said you may still want to define individual interfaces which inherit from the generic interface so as to define methods specific to each object.



Note/caveat:  Whilst generics are a very powerful feature in the language they are also incredibly easy to abuse, so if you're going to use them make sure it is for the right reason and fits your scenario.  Using them incorrectly can have a negative impact on your code.
Get it can you show me how to call the interface on .aspx front end?
You wouldn't call the interface, you would call the concrete type that implements the interface.

I can't provide a specific implementation as I don't know much about ASP.NET Web Forms, however, your implementation may look something like below.  How you choose to create an instance of PrincipalRepository into your page is up to you, whether it be by calling new, ore dependency injection.  I leave that choice to you.

public interface Repository<t>
{
    void Add(T item);
}

public class PrincipalRepository : Repository<IPrincipal>
{
    public void Add(IPrincipal principal)
    {
        throw new NotImplementedException(); // implement this
    }
}

public partial class SamplePage : System.Web.UI.Page 
{
    private readonly PrincipalRepository principalRepository;

    ...

    protected void Button1_Click(object sender, EventArgs e)
    {
        this.principalRepository.Add(...); // add your new principal
    }
}

Open in new window

Got it
It does not work  to me because I separated them into 3 different(.cs).
Anyway we can separated them?

interface.cs
public interface IRepository<T> where T : class
    {
        void Add(T item);
    }




namespace EE
{
     
    principal.cs
    public class PrincipalRepository : IRepository<IPrincipal>
    {
        public void Add(IPrincipal principal)
        {
            using (var ctx = new Context())
            {
                var newPrincipal = new Principal {PrincipalName = principal.PrincipalName};
                ctx.Principals.Add(newPrincipal);
                ctx.SaveChanges();
            }
        }
    }

    Indemnitor.cs
    public class IndemnitorRepository : IRepository<Indemnitor>
    {
        public void Add(Indemnitor indemnitor)
        {
            using (var ctx = new Context())
            {
                var newIndemnitor = new Indemnitor
                {
                    FirstName = indemnitor.FirstName,
                    LastName = indemnitor.LastName,
                    MiddleName = indemnitor.MiddleName
                };
                ctx.Indemnitors.Add(newIndemnitor);
                ctx.SaveChanges();
            }
        }
    }
}
They can be split into separate files if you want, you must make sure you add the correct using statements if the namespaces do not match, or DLL references if they are in different assembly projects.
I tried and still complaints the same error message.
What is the error message?
Like I create a new cs called IQuote.cs and below is what I added

 public interface IQuote<T> where T: class
    {
        void AddPrincipal(T item);
        void AddIndmenitor(T item);
    }
error: does not implement interface member ......
The reason for that error has been explained several times now, along with how to resolve it.

Any methods you define in an interface MUST be implemented on the inheriting class(es).
so you are saying One interface can not put two classes/methods?
An interface can be inherited by one or more classes, the number is not limited.

What you MUST do though is provide an implementation for each of the methods defined in the interface in each of the classes that inherits from it.  You cannot define two methods in your interface and only implement one of them in inheriting classes, that is not how interfaces work.

You were spot on with the implementation you did in THIS comment.  What was wrong with that?
Okay. I followed your suggestions. However, I try to call the interface and always get below message.

Object reference not set to an instance of an object.

private readonly IPrincipal i;
        protected void Page_Load(object sender, EventArgs e)
        {          
          Principal newPrincipal = new Principal() { PrincipalName = "John Smiths" };
          i.Add(newPrincipal);          
        }
You cannot call an interface, you call one of the concrete type implementations which inherits from the interface

private readonly principalRepository;

protected void Page_Load(object sender, EventArgs e)
{
    // I assume your principalRepository is not null at this point
    Principal newPrincipal = new Principal() { PrincipalName = "John Smiths" };
    principalRepository.Add(newPrincipal);
}

Open in new window

when I  type principalRepository. I don't see "add"
and if I can't call interface. What is the point to use interface?
when I  type principalRepository. I don't see "add"

Has your implementation of PrincipalRepository inherited from IRepository<IPrincipal>?

and if I can't call interface. What is the point to use interface?

The point of an interface is to define a contract of behaviour and characteristics which are common/shared between related objects without defining the specific implementation.  Objects which inherit an interface must then provide their own implementation of the method.  You can then define methods or constructors as requiring the interface as an argument instead of a concrete type, mean you can pass it any object which inherits the interface.

Take a look at the following example:

namespace EE.Q_28552618.InterfaceExample
{
    using System;

    internal class Program
    {
        private static void Main(string[] args)
        {
            var dog = new Dog();
            var fish = new Fish();

            var animalConsumer = new AnimalConsumer(); // I don't mean it eats animals ...
            animalConsumer.DescribeAnimal(dog);
            animalConsumer.DescribeAnimal(fish);
        }
    }

    public class AnimalConsumer
    {
        // Note the interface is an argument, not the concrete type fish or dog
        public void DescribeAnimal(IAnimal animal)
        {
            // this doesn't care what type of animal it is
            // it only cares that the Describe() methods has been implemented
            animal.Describe();
        }
    }

    public interface IAnimal
    {
        void Describe();
    }

    public class Fish : IAnimal
    {
        public void Describe()
        {
            Console.WriteLine("I am a fish");
        }
    }

    public class Dog : IAnimal
    {
        public void Describe()
        {
            Console.WriteLine("I am a Dog");
        }
    }
}

Open in new window


I do feel as though we are going around in circles here.  Without intending to be rude and considering we've shown you how interfaces work several times now, I suggest that if you still do not understand how interfaces work or should be used, you stop using them until you have done some research on them and how to implement them.

http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-13.aspx
http://csharp.net-tutorials.com/classes/interfaces/
Below is working to me. However, I have to call PrincipalRepository to get everything done.

Then why I need to write the codes for IPrincipal.cs

I just don't see a function, validation, and etc that affect to below codes.
So all the codes I use, I can directly call PrincipalRepository and I don't need interface to do anything for me....

Can you explain to me based on my codes. Why I need to use Interface?




PrincipalRepository.cs
public class PrincipalRepository:IPrincipal
    {      
      public ICollection<Principal> GetList()
       {
           using (var ctx = new Context())
           {
               List<Principal> domain = (from d in ctx.Principals select d).ToList();
               return domain;
           }
       }
      public void Add(Principal principal)
            {
                using (var ctx = new Context())
                {
                    //query table name and found no duplicate                        
                    Principal domain = (from d in ctx.Principals where d.PrincipalName.Trim().ToLower() == principal.PrincipalName.Trim().ToLower() select d).FirstOrDefault();

                    if (domain == null || string.IsNullOrEmpty(domain.PrincipalName) == true)
                    {
                        Principal newPrincipal = new Principal() { PrincipalName = principal.PrincipalName };
                        ctx.Principals.Add(newPrincipal);
                        ctx.SaveChanges();                        
                    }
                }  
       }    
    }    



IPrincipal.cs
public interface IPrincipal
    {
      ICollection<Principal> GetList();        
      void Add(Principal principal);
    }




To implement on frontend aspx

protected void submit_Click(object sender, EventArgs e)
        {
            Principal newPrincipal = new Principal() { PrincipalName = Name.Text.Trim() };
            Surety.Repository.PrincipalRepository x = new PrincipalRepository();
            x.Add(newPrincipal);
            DataBind();
        }
        public void DataBind()
        {            
            Surety.Repository.PrincipalRepository x = new PrincipalRepository();
            ICollection<Principal> list = x.GetList();
            DatalistPrincipal.DataSource = list;
            DatalistPrincipal.DataBind();    
        }
@ITSolutionWizard.
You asked a question.
JamesBurger answered in words.  You didn't seem to understand and asked for a code example.  That was provided by me and later a complete example by Tchuki.
You then continued by extending your code, introducing the same problem, and asking what was wrong.  Experts here repeated how to fix it.
You have then continued with rather more complex examples and are repeating the same errors that you were told how to correct in the very first comment.

PLEASE READ THE COMMENTS.  I do not know how to explain in more simple terms.

I, for one, can not explain it more simply.
All you have to read is my last message.
Interfaces provide a level of abstraction from the implementation detail of the behaviours they define.  They also promote polymorphism through inheritance and code reuse via providing interfaces as arguments rather than concrete types.

That being said interfaces are not a silver bullet, they do not solve all your problems and should not be implemented merely because it is what the cool kids are doing or you think it would be fun.  Adding abstractions for the sake of it merely increases complexity without providing benefit, don't do it.

Introducing a programming paradigm into your code simply because you think it would be fun or interesting but without having reason will more than likely come back to bite you in the ass.  Only implement what you must, when you must.
Tchuki: I need you to explain to me based on the my codes.(Posted on 2014-11-10 at 14:12:59).
First of all, I need to point out that I did not read all the posts in details, I do not have the time to go through such a long discussion. So, maybe my following comment is completely wrong because I missed something in the discussion. But from what I can see from a quick overview, I hope I can help you with my opinion.

The "my code" is not important here if you do not understand what an interface is and what it does, which I think is the problem. The programmers who answered up to now tried to make you understand what an interface is about, but you seem to keep concentrating on your code. You do not try to understand what they say to you, you simply want your code to work, without ever asking the real question: "Is an interface the right thing to use here?"

If you were trying to understand what is said instead of focusing on making your code work, you would learn something.

You can argue for hours to try to find a way to return a value from your Sub, but it is not the role of a Sub. This is the role of a Function. Maybe it's the same thing here. An Interface might not be what you need.

Sometimes, you have to scrap your code and start anew with another way of doing things. Instead of focusing on the code, if I were you, I would post a new question, explaining what you want to do, something I did not see in my quick review of the posts. Make my code work, but not how could I do this and that. It;s worthless to try to understand a mechanism if you try to apply it to something for which it was not meant to be.

I have a feeling that it is the case here.
It is about what I need or what I don't need. The codes I have is very easy to understand. and it is good for an example.
I just want to learn more in a real case. You can find many sample and theory on the web. How to implement is what I want to know and learn.

I want to use Interface - using in a right way. And so far I don't see the answer.  That is what I feel. However, I do appreciate people here taking his/her time to help and discuss.

Thanks
i mean "It is not about what I need or what I don't need"....sorry
>>I want to use Interface - using in a right way. And so far I don't see the answer.

Actually you asked a question - which has been answered:
Alert error pointing to void Add() inside of the interface
why? and how to fix it?


I'd suggest you close this question and ask another one about what you now want.


ps.  The experts here are volunteers, an answer involving writing an essay probably is not going to appear.  Something like this is more suitable for reading about in a good C# programming book.  There it will go into detail.
Split or the very first comment.
This answered the question in words.
https://www.experts-exchange.com/questions/28552618/c-interface.html?anchorAnswerId=40427658#a40427658
The asker requested code (maybe it wasn't clear what was meant).
This comment used the code supplied in the question to display what was meant.
https://www.experts-exchange.com/questions/28552618/c-interface.html?anchorAnswerId=40427819#a40427819

Further comments from all three experts supplied related information.
The first comment by Jacques Bourgeois answers the question that was asked and AndyAinscow did provide the initial code example.  These two comments could be deemed as appropriate answers for the original question.  These two comments also should in theory provide sufficient information for anyone with a similar query reviewing the question enough information (assuming a certain level of knowledge) to resolve their issue.

With that in mind it can be seen from the other comments that the author did not fully comprehend what was being said and requested further assistance not dissimilar from the original question.  This resulted in a circular discussion of questions and explanations/examples which again the question author did not appear to understand.

I do not know what the protocol of EE is in a scenario such as this.  If EE like to maintain questions which have answers regardless of the question author feeling as though they got their answer, then I would possibly close the question with the suggested comment(s) as the answer(s).  Otherwise I would be happy to see the question deleted considering the questions author did not appear to get their answer (albeit they got answers but did not understand).