Почему я не могу добавить класс в интерфейс - PullRequest
0 голосов
/ 06 декабря 2018

Я могу сделать это:

public interface IConn
{
    bool Check();
}

public class Conn : IConn
{
    public bool Check() { //Method }
}

Но я не могу сделать это:

public class CustomClass { }

public interface IConn
{
    CustomClass CC();
}

public class Conn : IConn
{
    public CustomClass CC = new CustomClass();
}

Вместо этого наследование интерфейса заставляет меня применить это:

public class Conn : IConn
{
    CustomClass IConn.CC()
    {
        throw new NotImplementedException();
    }
}

Моя цель состоит в том, чтобы создать ссылку на CustomClass в интерфейсе (для intellisense), а затем просто создать экземпляр этого и выполнить его в классе Conn.

Возможно ли это?Как я могу это сделать?Почему интерфейс превращает свойство, являющееся классом, в метод?

Ответы [ 5 ]

0 голосов
/ 06 декабря 2018

Я немного изменил ваш код.Пожалуйста, посмотрите, поможет ли это -

   public class CustomClass {      }

   interface IConn
   {
       CustomClass CC();
   }

   public class Conn : IConn
   {
      public CustomClass CC()
      {
         return  new CustomClass();
      }
   }
0 голосов
/ 06 декабря 2018

Вы можете «добавить класс к интерфейсу», хотя я должен заметить, что надеюсь, что я правильно понял, что вы имели в виду, потому что предложение не имеет никакого смысла.

Но давайте посмотрим, что выdid:

public class CustomClass { }

public interface IConn
{
    CustomClass CC();
}

Здесь объявляется класс CustomClass и интерфейс IConn, а в интерфейсе вы объявляете метод CC, который возвращает ссылку на CustomClassobject.

Пока все хорошо.

Затем вы пытаетесь реализовать интерфейс, и вот тут возникают ваши проблемы:

public class Conn : IConn
{
    public CustomClass CC = new CustomClass();
}

Здесь компиляторпожаловаться:

CS0535 «Conn» не реализует элемент интерфейса «IConn.CC ()»

Причина в том, что в интерфейсе CCэто метод , но в классе, в котором вы пытались реализовать интерфейс, вы сделали CC поле .

, чтобы интерфейс был успешным и легальнымреализуется классом, вы должны оба реализовать все члены интерфейса, и вы должныдополняйте их, используя один и тот же тип члена.

Так что, если вы объявите CC как метод в интерфейсе, он должен быть реализован как метод в классе, это не обойдется.

Таким образом, вы можете просто изменить свой класс следующим образом:

public class Conn : IConn
{
    public CustomClass CC()
    {
        return new CustomClass();
    }
}

или, если вы работаете в более новой версии C #, где у вас есть члены с выражениями в выражениях, вы можете написать это так:

public class Conn : IConn
{
    public CustomClass CC() => new CustomClass();
}

Это всего лишь несколько дополнительных символов от того, что у вас было.


Теперь, что, если я неправильно понял ваш вопрос, и вы действительно хотели, чтобы все разработчики вашего интерфейса реализовали поле?Ну, вы не можете этого сделать.

В интерфейсе вы можете только объявить свойства и методы, а не поля, не конструкторы или другие вещи.


Теперь, кроме того, выскажем так:

Вместо этого наследование интерфейса заставляет меня применить это:

public class Conn : IConn
{
    CustomClass IConn.CC()
    {
        throw new NotImplementedException();
    }
}

Я догадываюсь , что в то время, когда вы думали об этомбыл единственный законный способ реализовать этот метод, у вас все еще было поле, потому что вы не можете сделать открытый метод и полем, оба с одинаковым именем, это недопустимо:

public class Conn : IConn
{
    public CustomClass CC = new CustomClass();
    public CustomClass CC() => new CustomClass();
}

и вы получите это:

CS0102 Тип 'Conn' уже содержит определение для 'CC'

Однако, если вы вместо этого сделаете метод явнореализовать интерфейс, как это, он будет компилироваться:

public class Conn : IConn
{
    public CustomClass CC = new CustomClass();
    CustomClass IConn.CC() => new CustomClass();
}

Однако теперь у вас есть два члена с именем CC, один из которых доступен только через интерфейс, и, вероятно, не то, чтоВы хотите.


Окончательные указания здесь.Если вы намереваетесь удерживать ссылку на CustomClass, даже если эта ссылка создается внутри класса, реализующего IConn, вам следует вместо этого объявить и реализовать CC как свойство.

Однако, если вы хотите, чтобы каждый раз, когда вы «читали» CC (читали свойство или вызывали метод, в зависимости от того, как вы решили объявить и реализовать его), вы получите новый экземпляр CustomClass, то, по моему мнению, вы должны придерживаться метода.

0 голосов
/ 06 декабря 2018

Кажется, вы хотите добавить поле в интерфейс, чтобы все классы, реализующие его, должны были иметь это поле.Поля не допускаются в интерфейсах, но свойства есть.Свойства очень похожи на поля, и у вас все равно не должно быть открытых полей.

public class CustomClass { }

public interface IConn
{
    CustomClass CC { get; set; } // or just "get;"
}

public class Conn : IConn
{
    // I have changed this to a property.
    public CustomClass CC { get; set; } = new CustomClass();
}

В качестве альтернативы вы можете использовать вместо этого метод:

public class CustomClass { }

public interface IConn
{
    CustomClass CC();
}

public class Conn : IConn
{
    // this will always return a new instance of CustomClass, which is
    // not the same behaviour as the code in your attempt.
    public CustomClass CC() {
        return new CustomClass();
    }
}
0 голосов
/ 06 декабря 2018

На самом деле у вас есть две проблемы:

  1. Ваш интерфейс определяет метод , поэтому вашему классу реализации также необходим метод с точно таким же именем иточно такой же список параметров.Кажется, вам нужно свойство вместо метода.
  2. В вашем классе есть открытое поле, которое не реализует что-либо , поскольку оно не разрешено для интерфейса.На самом деле для интерфейса допускаются только методы.Однако, поскольку свойства - это не что иное, как набор методов get и set, созданных компилятором, вы также можете определить их в интерфейсе.

Поэтому используйте следующее:

public interface IConn
{
    CustomClass CC { get; set; }
}

public class Conn : IConn
{
    public CustomClass CC { get; set; }
}
0 голосов
/ 06 декабря 2018

Вы определяете метод в интерфейсе.То, что вы действительно хотите, это свойство

public interface IConn
{
   CustomClass CC { get; set }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...