C#中存在无法解释的歧义,在此我明确尝试调用构造函数,但编译器认为它是不同的构造函数。我将首先展示我们使用的简短C#体系结构。然后显示我创建的一个小“工作”示例,以及可能的解决方案,但我仍然想理解为什么会发生这种情况。
架构:
我创建的示例
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,因此,通过添加[assembly: InternalsVisibleTo("OneClient")]
到包裹CLR的DLL的'AssemblyInfo.cs',内部组件可以暴露给内部客户端水平。
问题
编译客户端代码时,出现以下错误: 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'.
InnerOne
因为不允许客户端使用此级别。A(string val)
和A(AInner inner)
构造。可能的解决方法:
[assembly: InternalsVisibleTo("OneClient")]
-由于特定客户端需要使用其他内部类,因此这是不可接受的。A(string val)
构造函数更改为A(string val, bool unique=true)
并使用它A testA = new A(myString, true)
-不是一个好的解决方案。A()
并调用testA.Val = myString;
-这实际上可以,但是需要很多代码。A testA = new A(myString)
为A testA = new A(val:myString);
-这实际上是选择的解决方案。题
为什么会发生这种歧义?
A(string val)
,myString
实际上是一个string
值,这很奇怪。这是Microsoft编译器中的错误吗?
示例源:源代码One.zip
为什么会发生这种歧义?
因为要满足构造函数的重载分辨率,所以编译器需要知道所有参数类型是什么,并且它不知道anAInner
是什么。
为什么不将AInner
版本公开为工厂方法:
static internal A Create(AInner inner)
{
return new A { _inner = inner };
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句