我的问题的前提是:
- 有一个名为
Foo
的库,它依赖于一个名为Bar
的库 Foo
中的一个类继承了Bar
中的一个类Foo
定义了一些属性/方法,只是简单地通过Bar
进行传递- 一个名为
FooBar
的应用程序仅依赖于Foo
考虑以下示例:
class Program
{
static void Main(string[] args)
{
Foo foo = Foo.Instance;
int id = foo.Id; // Compiler is happy
foo.DoWorkOnBar(); // Compiler is not happy
}
}
Foo 的定义如下。public class Foo : Bar
{
public new static Foo Instance { get => (Foo)Bar.Instance; }
public new int Id { get => Bar.Id; }
public void DoWorkOnBar()
{
Instance.DoWork();
}
}
Bar的定义如下
public class Bar
{
public static Bar Instance { get => new Bar(); }
public static int Id { get => 5; }
public void DoWork() { }
}
这个完全让我无法理解的部分:
没有引用Bar
库
FooBar
可以检索到由Bar
提供的ID(至少它可以编译)FooBar
不能请求Foo执行最终由Bar
完成的工作
foo.DoWorkOnBar();
相关的编译器错误是:
类型“Bar”在未被引用的程序集中定义。您必须添加对程序集“Bar、版本1.0.0.0、Culture=Neutral、PublicKeyToken=null”的引用。
为什么编译器似乎存在差异?
我原本以为,如果没有FooBar
添加对Bar
的引用,这两个操作都不会编译。
public class Bar { }
和public class Foo : Bar { public static Foo Instance => null; public int Id => 42; public DoWorkOnBar() { } }
,问题是否仍然存在?猜测:这可能与方法可以重载而属性不能有关。 - user4003407public class Foo:Bar {public static int P => 0; public static int M()=> 0;}
。调用Foo.P
没有问题;调用Foo.M()
会使编译器要求使用Bar
。为什么?这可能需要一个编译器编写者进一步解释。(但是@PetSerAl的猜测“责怪过载分辨率”是安全的,因为这是语言中迄今为止最复杂的部分,并且有许多有趣的黑暗角落。) - Jeroen MostertFoo
和Bar
的实现减少到最小必要版本以重现错误,这样其他人就不会因为额外的干扰而走错路。 - user4003407