2014-01-26 6 views
1

У меня возникли проблемы с явным интерфейсом, который я создал, и я получаю исключение,Декларирование Явные интерфейсы и не содержит ошибки определения C#

«х» не содержит определения для «у ', а метод расширения' y ', принимающий первый аргумент типа' x ', не найден

У меня есть серия классов. Базовый класс:

public interface IFactoryResponse 
{ 
    object instance { get; set; } 
    string instanceconfig { get; set; } 
} 

класс, который явно реализует его:

public class FactoryResponseImpl : IFactoryResponse 
{ 
    object IFactoryResponse.instance { 
     get { return ((IFactoryResponse)this).instance; } 
     set { ((IFactoryResponse)this).instance = value; } 
    } 

    string IFactoryResponse.instanceconfig { 
     get { return ((IFactoryResponse)this).instanceconfig; } 
     set { ((IFactoryResponse)this).instanceconfig = value; } 
    } 
} 

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

if (facconfig.useabstract) { 
    response.instance = Activator.CreateInstance(m_entassembly.GetType(entconfig.Classname, true, true)); 
    response.instanceconfig = facconfig.config; 
} else { 
    Assembly assem = Assembly.LoadFrom(facconfig.assemblyfile); 
    object Obj = Activator.CreateInstance(assem.GetType(facconfig.Classname, true, true)); 
    response.instance = Obj; 
    response.instanceconfig = facconfig.config; 
} 
+0

Является ли интерфейс определенным в той же сборке? –

+0

Это действительно определено в той же сборке – SoftwareSavant

+0

, вам нужно отобразить объект в качестве этого интерфейса, после чего вы можете увидеть свойства –

ответ

3
  1. Ваша реализация неверен. Это вызовет StackOverflowException, потому что свойство называет себя. Вы можете легко реализовать свойства, используя autoproperties:

    public class FactoryResponseImpl : IFactoryResponse 
    { 
        object IFactoryResponse.instance { get; set; } 
    
        string IFactoryResponse.instanceconfig { get; set; } 
    } 
    
  2. Когда элемент интерфейса реализован в явном виде, вы должны смотреть на переменном в качестве интерфейса, либо литья экземпляра класса для этого интерфейса или назначая его в переменные тип как этот интерфейс.

    if (facconfig.useabstract) { 
        ((IFactoryResponse)response).instance = Activator.CreateInstance(m_entassembly.GetType(entconfig.Classname, true, true)); 
        ((IFactoryResponse)response).instanceconfig = facconfig.config; 
    } else { 
        Assembly assem = Assembly.LoadFrom(facconfig.assemblyfile); 
        object Obj = Activator.CreateInstance(assem.GetType(facconfig.Classname, true, true)); 
        ((IFactoryResponse)response).instance = Obj; 
        ((IFactoryResponse)response).instanceconfig = facconfig.config; 
    } 
    
  3. Зачем нужен интерфейс, который будет реализован явно? Вы не должны этого делать, если у вас нет веских оснований. При неявной реализации все намного проще:

    public class FactoryResponseImpl : IFactoryResponse 
    { 
        public object instance { get; set; } 
    
        public string instanceconfig { get; set; } 
    } 
    

    И ваш другой код должен работать нормально.

+0

Это очень хороший ответ. Каждый раз, когда я думаю, что знаю все, что мне нужно знать, я столкнулся с такой проблемой. Мне нужно пережить это немного больше, но я думаю, что ваш ответ лучший. Я просто собираюсь устранить явные реализации интерфейсов. – SoftwareSavant

0

Ваши явные реализации ссылаются на самих себя. Вы должны ссылаться на частное поле или публичную реализацию. Например .:

public class FactoryResponseImpl : IFactoryResponse 
{ 
    DatabaseFactoryResponseInstance _instance; 

    public FactoryResponseImpl() 
    { 
     _instance = new DatabaseFactoryResponseInstance(); 
    } 

    object IFactoryResponse.instance { 
    get { return (object)_instance; } 
    set { 
      if (value != null) 
      { 
       DatabaseFactoryResponseInstance dbInstance; 
       dbInstance = value as DatabaseFactoryResponseInstance; 
       if (dbInstance == null) 
        throw new InvalidOperationException(); 

       _instance = dbInstance; 
      } 
     } 
} 
+0

Откуда появился DatabaseFactoryResponseInstance? – SoftwareSavant

+0

Это одна из возможных реализаций 'instance'. –

+0

duh, Глупый меня. Я думал, что что-то пропустил. – SoftwareSavant

0

Это то, к чему вы стремились?

public interface IFactoryResponse 
     { 
      object instance { get; set; } 
      string instanceconfig { get; set; } 
     } 

     public class FactoryResponseImpl : IFactoryResponse 
     { 
      object IFactoryResponse.instance { get; set; } 
      string IFactoryResponse.instanceconfig { get; set; } 
     } 

     class Test 
     { 
      public void TestMethod() 
      { 

       IFactoryResponse response = new FactoryResponseImpl(); 
       response.instance = null; 
      } 
     } 
0

Если один использует явные реализации интерфейса, как IFactoryResponse.instance, то эти методы не являются общедоступными. Либо вам нужно передать IFactoryResponse для доступа к ним, либо определить методы как public: public object instance {...}.