C# 当一个对象对其实现的接口有引用时,该对象会存在吗?
我有一个实现接口的类。我不需要引用那个类的对象,只需要引用它们的接口。它看起来像:C# 当一个对象对其实现的接口有引用时,该对象会存在吗?,c#,.net,interface,garbage-collection,C#,.net,Interface,Garbage Collection,我有一个实现接口的类。我不需要引用那个类的对象,只需要引用它们的接口。它看起来像: interface A {} class B : A {} //in code: A a = (A) new B(); 我的问题是:当我有一个对B的a的引用时,B的实例是否会存在(不通过GC收集)?是的,因为您仍然有一个对新B()的引用,尽管您只能看到实现该接口的部分a是的,因为您仍然有一个对新B()的引用尽管您只能看到实现该接口的部分A,但无论您的变量类型是类还是接口,引用都是相同的实际值。因此,是的:它
interface A {}
class B : A {}
//in code:
A a = (A) new B();
我的问题是:当我有一个对B的a的引用时,B的实例是否会存在(不通过GC收集)?是的,因为您仍然有一个对
新B()的引用,尽管您只能看到实现该接口的部分a是的,因为您仍然有一个对新B()的引用
尽管您只能看到实现该接口的部分A
,但无论您的变量类型是类还是接口,引用都是相同的实际值。因此,是的:它将保持活动状态。无论变量类型是类还是接口,引用都是相同的实际值。因此,是的:它将保持活动状态。是的,对象的实例是相同的,您可以将对象强制转换到其任何实现的接口,但实例是一个。是的,对象的实例是相同的,您可以将对象强制转换到其任何实现的接口,但实例是一个。是的,因为通过接口对对象的引用仍然是对该对象的引用
将对象强制转换到接口并不会创建新对象,它只会更改您用来与对象进行对话的“门户”
您可以通过以下方式轻松测试:
执行时,您将获得:
到这里
然后,可选地:
B最后确定
但是请注意,B在整个GC循环中幸存了下来,即使您通过a对它进行了引用。是的,因为通过接口对对象的引用仍然是对该对象的引用
将对象强制转换到接口并不会创建新对象,它只会更改您用来与对象进行对话的“门户”
您可以通过以下方式轻松测试:
执行时,您将获得:
到这里
然后,可选地:
B最后确定
但是请注意,B在整个GC循环中幸存了下来,即使您通过a有一个对它的引用。您不能有对接口的引用。您可以有一个对实现接口的对象的引用。@Ace-我不认为这个问题建议创建这样的接口;但实际上,在互操作代码中,您可以new()
一个接口(编译器中对此有一个漏洞):您不能有对接口的引用。您可以有一个对实现接口的对象的引用。@Ace-我不认为这个问题建议创建这样的接口;但实际上,在互操作代码中,您可以new()
一个接口(编译器中对此有一个漏洞):将类类型对象强制转换到接口并不会创建一个新对象;正如您所注意到的,编译器知道将所讨论的对象视为接口,但它仍然是一样的。但是,将结构强制转换到接口会创建一个与原始对象不相交的新对象。出于这个原因,结构应该很少实现接口,除非泛型可以允许在没有类型转换的情况下使用接口(如IComparable)。这就是为什么我说“object”,但是的,结构是不同的。将类类型对象转换为接口不会创建新对象;正如您所注意到的,编译器知道将所讨论的对象视为接口,但它仍然是一样的。但是,将结构强制转换到接口会创建一个与原始对象不相交的新对象。出于这个原因,除了泛型允许在没有类型转换的情况下使用接口(如IComparable)外,结构很少实现接口。这就是为什么我说“object”,但是的,结构是不同的。
void Main()
{
A a = (A)new B();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.KeepAlive(a);
Debug.WriteLine("Got here");
}
public interface A
{
}
public class B : A
{
~B()
{
Debug.WriteLine("B was finalized");
}
}