【问题标题】:Declaring Explicit interfaces and the does not contain a definition error C#声明显式接口并且不包含定义错误 C#
【发布时间】:2014-01-26 18:09:23
【问题描述】:

我创建的显式接口存在问题,并且出现异常,

“x”不包含“y”的定义,并且找不到接受“x”类型的第一个参数的扩展方法“y”

我有一系列的课程。基类:

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 可以找到接口和类,但它无法解析实例属性。我在这里想念什么。我可能遗漏了更精细的显式继承规则之一。

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;
}

【问题讨论】:

  • 接口是否定义在同一个程序集中?
  • 确实是在同一个程序集中定义的
  • 您需要将对象转换为该接口,然后您才能看到属性
  • 这不是等待发生的堆栈溢出异常吗? return ((IFactoryResponse)this).instance;
  • 如果我错了,请纠正我,但看起来您的财产自称。

标签: c# class interface explicit-implementation


【解决方案1】:
  1. 您的实现不正确。它将导致StackOverflowException,因为属性调用自身。您可以使用自动属性轻松实现属性:

    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; }
    }
    

    您的其他代码应该可以正常工作。

【讨论】:

  • 这是一个很好的答案。每次我认为我知道我需要知道的一切时,我都会遇到这样的问题。我需要再讨论一下,但我认为你的答案是最好的。我只是要消除显式接口实现。
【解决方案2】:

您的显式实现正在引用它们自己。您应该引用私有字段或公共实现。例如:

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;
            }
         }
}

【讨论】:

  • DatabaseFactoryResponseInstance 是从哪里来的?
  • 这是instance 的一种可能实现。
  • 呃,我真傻。我以为我错过了什么。
【解决方案3】:

这就是你的目标吗?

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;
            } 
        }

【讨论】:

    【解决方案4】:

    如果使用像 IFactoryResponse.instance 这样的显式接口实现,那么这些方法是不公开的。您要么需要强制转换为 IFactoryResponse 才能访问它们,要么将方法定义为 public:public object instance { ... }。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2013-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      相关资源
      最近更新 更多