隐式转换不能分配给接口

Bra*_*ner 1 c# implicit-conversion

我有一个隐式转换的类string定义为:

class TestClass : ITestInterface
{
    public static implicit operator TestClass(string value)
    {
        return new TestClass(value);
    }

    public TestClass(string value)
    {
        Value = value;
    }
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

它实现了一个标记界面:

public interface ITestInterface { }
Run Code Online (Sandbox Code Playgroud)

我有另一个类的方法定义为:

public void DoSomething(ITestInterface thing) { }
Run Code Online (Sandbox Code Playgroud)

我试图调用该方法时遇到错误:

public void Test()
{
    TestClass a = "This works fine.";
    DoSomething("Why doesn't this work?");
}
Run Code Online (Sandbox Code Playgroud)

无法从'string'转换为'Tests.ITestInterface'

所有代码都大大简化了; 我的实际需求要复杂得多,但这似乎是阻碍我想实现的模式的核心.

什么阻止这种工作?(C#规范中的东西?)
我可以对我的代码进行任何更改以允许这种类型的转换工作吗?

Fla*_*ter 5

您省略了解释该问题的第三个选项:

//1
TestClass a = "This works fine.";

//2
ITestInterface i = "This doesn't work either!";

//3
DoSomething("Why doesn't this work?");
Run Code Online (Sandbox Code Playgroud)

(1)中,你已经宣布了TestClass a.这意味着编译器知道当你使用不同的类型(在这种情况下是字符串)时,它应该尝试将所述值转换为TestClass.

(2)中,你已经宣布了ITestInterface i.这意味着编译器知道当你使用不同的类型(在这种情况下是字符串)时,它应该尝试将所述值转换为ITestInterface.

这是问题的根源.在string和之间没有定义转换ITestInterface.

你现在在想的是:

好吧,知道我希望将它转换为TestClass.为什么编译器没有弄清楚我想要它做什么?

简短的回答是编译器拒绝猜测.

你想要发生什么会导致不可能的情况.例如,如果有第二个类也会实现会发生什么ITestInterface

class SecondTestClass: ITestInterface
{
    public static implicit operator SecondTestClass(string url)
    {
        return new SecondTestClass(url);
    }

    public SecondTestClass(string url)
    {
        Value = GetValueFromTheInternet(url);
    }
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

让我们重新评估您的代码:

//1
TestClass a = "This works fine.";
Run Code Online (Sandbox Code Playgroud)

这有效.有一个转换stringTestClass.

//2
SecondTestClass b = "This works fine.";
Run Code Online (Sandbox Code Playgroud)

这有效.有一个转换stringSecondTestClass.

//3
ITestInterface i = "This still doesn't work!";

//4
DoSomething("This doesn't work for the same reason as //3");
Run Code Online (Sandbox Code Playgroud)

这不起作用.编译器不具有任何已知的转换stringITestInterface.

编译器无法确定是否要将其转换为a TestClass然后分配给i,或者如果您希望将其转换为a SecondTestClass然后分配给i.

而且,正如我之前所说,编译器拒绝猜测.

另外,为了清楚起见,这可行:

TestClass a = "This works fine.";

ITestInterface i1 = a;
DoSomething(a);
DoSomething(i1);

SecondTestClass b = "This works fine.";

ITestInterface i2 = b;
DoSomething(b);
DoSomething(i2);
Run Code Online (Sandbox Code Playgroud)

所有这些任务都有效.

您的问题的关键是编译器希望您明确说明要将字符串转换为哪种类型.在你自己的例子中,你已经明确要求了TestClass.请注意,如果您使用过,这将不起作用var,因为编译器在这种情况下也无法弄清楚.