微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

具有显式调用的C#构造函数歧义-错误CS0012

如何解决具有显式调用的C#构造函数歧义-错误CS0012

C#中存在无法解释的歧义,我在其中明确尝试调用构造函数,但编译器认为它是不同的构造函数。我将首先展示我们使用的简短C#体系结构。然后显示一个我创建的小“工作”示例,以及可能的解决方案,但我仍然想理解为什么会发生这种情况。

体系结构:

enter image description here

  1. 桥接C ++ API的CLR DLL。
  2. 使用桥接级别的C#API。
  3. 使用C#API的C#客户端应用程序。
  • 请注意,不允许C#客户端使用CLR级别。

我创建的示例

CLR DLL中的类:

#pragma once

#include <string>

using namespace System;

namespace Inner {
    public ref class AInner
    {
    public:

        AInner() : _data(new std::wstring(L"")) {}

        ~AInner() {
            delete _data;
        }

        property String^ Val
        {
            String^ get()
            {
                return gcnew String((*_data).data());
            }

            void set(String^ value) {
                System::IntPtr pVal = System::Runtime::InteropServices::Marshal::StringToHGlobalUni(value);
                *_data = (const wchar_t*)pVal.ToPointer();
                System::Runtime::InteropServices::Marshal::FreeHGlobal(pVal);
            }
        }

    private:

        std::wstring* _data;
    };
}

在DLL中包装CLR级别的类:

using System;

using Inner;

namespace Outer
{
    public class A
    {
        public A()
        {
            _inner.Val = String.Empty;
        }

        public A(string val)
        {
            init(val);
        }

        public string Val
        {
            get
            {
                return _inner.Val;
            }
            set
            {
                _inner.Val = value;
            }
        }

        internal A(AInner inner)
        {
            _inner = inner;
        }

        private void init(string Val)
        {
            _inner = new AInner();
            _inner.Val = String.Empty;
        }

        private AInner _inner;
    }
}

请注意,有一个internal构造函数一个public构造函数

使用C#API DLL的可执行客户端:

using Outer;

namespace OneClient
{
    class Program
    {
        static void Main(string[] args)
        {
            string myString = "Some String";
            A testA = new A(myString);
        }
    }
}

扭曲故事:

在包装CLR级别的DLL中,外部客户端不应使用所有API,而内部客户端可以使用所有API,因此,通过向'AssemblyInfo中添加[assembly: InternalsVisibleto("OneClient")],内部可以暴露给内部客户端。 DLL的cs包装CLR级别。

问题

编译客户端代码时,出现以下错误error CS0012: The type 'AInner' is defined in an assembly that is not referenced. You must add a reference to assembly 'InnerOne,Version=1.0.7600.28169,Culture=neutral,PublicKeyToken=null'.

  1. 我不能使用InnerOne,因为不允许客户使用此级别。
  2. 客户端同时接触A(string val)A(AInner inner)构造函数

可能的解决方法

  1. 删除[assembly: InternalsVisibleto("OneClient")]-由于特定客户端需要使用其他内部类,因此这是不可接受的。
  2. A(string val)构造函数更改为A(string val,bool unique=true)并使用它A testA = new A(myString,true)-不是一个好的解决方案。
  3. 使用认构造函数A()调用testA.Val = myString;-实际上可以,但是代码很多。
  4. 将客户端代码A testA = new A(myString)更改为A testA = new A(val:myString);-这实际上是选择的解决方案。

问题

为什么会出现这种歧义?

  • 我用A(string val)调用myString,实际上它是一个string的值 这很奇怪。

这是Microsoft编译器中的错误吗?

示例来源:代码One.zip

解决方法

为什么会出现这种歧义?

由于要满足构造函数的重载分辨率,编译器需要知道所有参数类型是什么,并且不知道AInner是什么。

为什么不将AInner版本公开为工厂方法:

static internal A Create(AInner inner)
{
    return new A { _inner = inner };
}
,

我看不到任何问题,问题在于我们习惯于以错误/简短的方式来做事情。

正确的答案是:

A testA = new A(val:myString);

此外,您的所有调用(以这种方式是对构造函数/初始化程序的调用,但无论如何都是调用)都应使用参数名称。没有人(甚至我)都写它们,但是...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?