简体   繁体   English

将接口变量分配给实现它的 class 失败

[英]Assigning interface variable to a class that implements it fails

  1. What is the problem?问题是什么?

I am working on a bigger project with a lot of code in between (.Net 4.5), but I will try to give you my current overview of the problem.我正在做一个更大的项目,中间有很多代码(.Net 4.5),但我会试着给你我目前对这个问题的概述。 I was trying to search for the similar question without success (sorry if it is a re-post).我试图搜索类似的问题但没有成功(对不起,如果它是重新发布的)。

Project A (class Library)项目 A(类库)

namespace nameA
{
    public interface ILog
    {
        bool GetFile(string a, string b, bool c);
        bool SetFile(string d);
    }
}

Project B (class Library) - Depends on project A项目 B(类库) - 取决于项目 A

using nameA;

namespace nameB
{
    public class ImplementInterface : ILog
    {
        // implementation of the interface + other methods
    }
}

Project C (class library) depends on projectA and projectB项目C(类库)依赖于projectA和projectB

using nameA;
using nameB;

namespace nameC
{
    public class SomeClass : IDisposable
    {
        public ImplementInterface _implementation { get; }

        public SomeClass()
        {
            _implementation = new ImplementInterface()
        }

        // unrelated implementation code ...

        private method Start()
        {
            ILog tmp = _implementation; // -> error CS0266: Cannot implicitly convert type 'nameB.ImplementInterface' to 'nameA.ILog'
            // ILog tmp = (ILog)_implementation; -> this will compile but it fails during runtime (usage of 'as' returns null)
        }
    }
}

As you can see from the sample above I have a problem that code will not compile due to conversion from child class to interface.从上面的示例中可以看出,由于从子 class 到接口的转换,代码无法编译。

If I do this example inside the same project everything will compile and code will work ok, also it will work ok if I implment SomeClass inside projectB and nameB namespace.如果我在同一个项目中执行此示例,一切都会编译并且代码可以正常工作,如果我在 projectB 和 nameB 命名空间中实现 SomeClass 也可以正常工作。 What I do not understand why it is not working.我不明白为什么它不起作用。

  1. Following things I tried:以下是我尝试过的事情:
  • Check is there any other implementation of ILog or ImplementInterface so that name resolution is the problem -> found none检查是否有 ILog 或 ImplementInterface 的任何其他实现,以便名称解析是问题 -> 没有找到
  • Check Assembly names and versions (so that I use correct assembly when running projectC) -> seems ok检查程序集名称和版本(以便在运行 projectC 时使用正确的程序集)-> 似乎没问题
  • Check that all Assembly's are loaded -> yep they are loaded检查所有程序集是否已加载-> 是的,它们已加载
  • Use refleaction to check for interface methods inside ImplementInterface -> methods seems to be there and reflection can find the interface implementation inside the class.使用反射检查实现接口内部的接口方法 - >方法似乎在那里,反射可以找到 class 内部的接口实现。
  • Implement SomeClass in project B and nameB -> seems that the problem is gone then, but it does not answer the question why is the problem there in the first place?在项目 B 和 nameB 中实现 SomeClass -> 似乎问题就消失了,但它没有回答为什么首先出现问题的问题?
  1. Assumptions假设
  • Well I have read about covariance contravariance but I do not think this can play any role here好吧,我已经阅读了有关协方差逆变的信息,但我认为这在这里不起作用
  • I think it is some small thing about name resolution or dll's loading我认为这是关于名称解析或 dll 加载的一些小事

I am not so familiar with this code base so it can also be something that I missed, but at this point I do not know what?我对这个代码库不太熟悉,所以它也可能是我错过的东西,但此时我不知道是什么?

EDIT: At the time I did not understand the problem correctly.编辑:当时我没有正确理解这个问题。 Here is small description what was the root cause of the above code not working.这是上面代码不起作用的根本原因的简短描述。

Project B form above that contains a class ImplementInterface which implements interface ILog, also used ILMerge tool (a .NET static linker library) ILMerge put all of the code from ProjectA (together with the interface from project A) to the.dll from the Project B. Since project C also used Project A and Project B, ILog interface was implemented twice and compiler refused to compile that with the error (error CS0266: Cannot implicitly convert type). Project B form above that contains a class ImplementInterface which implements interface ILog, also used ILMerge tool (a .NET static linker library) ILMerge put all of the code from ProjectA (together with the interface from project A) to the.dll from the Project B . 由于项目 C 也使用了项目 A 和项目 B,ILog 接口被实现了两次,编译器拒绝编译,错误(错误 CS0266:无法隐式转换类型)。 When I printed out all of the used assemblies non of them were showed twice since ILMerge merged the assemble of the project A to the project B.当我打印出所有使用过的程序集时,它们都没有显示两次,因为 ILMerge 将项目 A 的程序集合并到项目 B 中。

It is working fine for me.它对我来说很好。 Can you clean the code and change return type proper for private method Start().你能清理代码并更改私有方法 Start() 的返回类型吗? Also implement IDisposable interface.还实现 IDisposable 接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM