我有一个内部界面。通常我使用公共接口,但这次我在内部保留了很多东西。
现在问题是当我在一个实现内部接口的公共类中时,内部成员的容器为什么我不能在不进行转换(显式实现)的情况下访问接口成员?我在“所有者”类中,实现接口的类,完全在里面,我应该拥有所有权利,对吗?
我不介意如果我只在代码中使用一次,但事实并非如此。我在代码中有10次这样的星座。它有点烦人。
我错过了什么吗?就像我说的那样,我通常不会使用内部接口。
在开始downvoting或发布此问题的重复之前,只需删除评论即可将其删除。
这是代码:
internal class Poco
{
public string Str
{
get;
set;
}
}
internal interface ITest1
{
Poco Obj
{
get;
set;
}
}
public class Foo : ITest1
{
// Not working
Poco Obj
{
get;
set;
}
}
答案 0 :(得分:2)
您将internal
acces modfifier与接口的显式实现混淆。
接口为internal
这一事实与其在实现类中的可见性无关。它只限制了对当地集会的可见性。
显式实现允许名称冲突:
interface IKey1 { int ID { ... } }
interface IKey2 { int ID { ... } }
class MyOwnerClass : IKey1, IKey2 // requires explicit imp
{
int IKey1.ID { .... }
int IKey2.ID { .... }
// the only way to access this:
void Foo()
{
int i1 = ((IKey1)this).ID;
IKey2 ik2 = this;
int i2 = ik2.ID;
int i3 = ID; // error, otherwise: which one
}
}
您的核心问题:如何在不进行强制转换的情况下访问接口成员。在此示例中,对this.ID
的任何引用都是不明确的。
不允许隐式实现与冲突成员的接口。
为什么
private iKey.ID
无效。
编译器在这里控制可见性,并使其比“私有”更隐蔽。这类似于您无法在public
interface IA { ... }
的原因
完全不同的情况:
internal class Poco { ... } // this 'internal' is a problem
internal interface ITest1 // this isn't
{
Poco Obj { } // Poco is an internal type
}
public class Foo : ITest1
{
// Not working
Poco Obj { ... } // property _and_ type need to be public
}
您正试图在公共类上拥有公共财产,但内部类型 从外部程序集中查看它:
Foo f = ...; // OK, Foo is a public Type
f.Obj = ...; // but we don't know the Type of Obj here
答案 1 :(得分:2)
您可以拥有内部(甚至是私有)属性以及公开它的显式接口实现:
public class Foo : ITest1
{
internal Poco Obj { get; set; }
Poco ITest1.Obj { get { return Obj; } set { Obj = value; } }
}
这是“更改”界面成员可见性的推荐方法。许多.NET类使用此技术将接口成员转换为protected virtual
成员。
答案 2 :(得分:1)
这就是规范中定义显式接口的方式。
“显式”部分表示“我将告诉代码何时将该对象视为接口”,因此除非您告诉代码(通过强制转换),否则它将看不到接口的方法/属性。如果您有两个具有相同名称的方法的接口,这非常有用。
您可以拥有内部接口,但是您无法将其用于公开的类(有些原因,请参阅this post)。
以下是有效实施的示例:
internal interface IKeyable
{
int ID {get; set;}
}
internal class MyClass: IKeyable
{
public int ID { get; set; }
}
关于编辑问题:
有几件事情不适合这种情况:
Obj
类的Foo
属性(默认情况下)是私有的,因此无论是否有接口,它都无法在类外访问。Obj
不被视为ITest1
实施的合适人选1}} interface。Foo
是公开的,但Poco
是内部的,这意味着即使用户(从程序集外部将能够访问该类,他也无法访问该属性,这没有意义。如果你想向世界公开一个内部类(例如,暴露它的数据,但不是它的内部细节),你可以创建一个公共访问接口,或者创建一个知道要转换的公共访问类来自你的班级。
所以你可以这样做:
public interface IPoco {
string Title {get; } //restring writing, for example
}
internal class Poco : IPoco
{
public string Title {get; set; } //read/write access within the assembly
}
public class Foo
{
public IPoco MyPoco {get; set;}
}
或
public class PocoAccessor
{
public string Title {get; private set;}
internal static PocoAccessor ToPocoAccessor(Poco source)
{
return new PocoAccessor { Title = source.Title}
}
}
public class Foo
{
public PocoAccessor MyPoco {get; set;}
}
答案 3 :(得分:0)
您的财产仍缺少类型。即使您要将其声明为接口成员的显式实现,仍需要指定类型。
class MyOwnerClass : iKey
{
int id;
int iKey.ID
{
get {return this.id;}
set { this.id = value;}
}
}
为接口iKey提供的“内部”访问修饰符只会使它在定义的命名空间之外不可见。没有更多,也没有更少。此外,正如一些人所指出的,接口更好的命名约定是使用描述预期功能集的形容词,前缀为“I”。
internal class Poco
{
public string Str
{
get;
set;
}
}
internal interface ITest1
{
Poco Obj
{
get;
set;
}
}
public class Foo : ITest1
{
Poco Obj // missing access modifier
{
get;
set;
}
}
没有为Obj指定访问修饰符,这使其成为私有。