访问所有者类中的内部接口
本文关键字:内部 接口 所有者 访问 | 更新日期: 2023-09-27 18:34:16
我有一个内部接口。通常我使用公共接口,但这次我把很多东西都保留在内部。
现在的问题是,当我在一个实现内部接口的公共类中时,该接口进一步容器了内部成员,为什么我不能在不强制转换(显式实现(的情况下访问接口成员?我在"所有者"类内部,实现接口的类,完全在内部,我应该拥有所有权限,对吧?
我不介意我只在代码中使用一次该转换,但事实并非如此。我在代码中有 10 次这样的星座。有点烦人。
我错过了什么吗?就像我说的,我不能正常使用内部接口。
在您开始反对或发布此问题如何重复之前,只需发表评论,我会将其删除。
这是代码:
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;
}
}
您将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
不起作用。
编译器在这里控制可见性,并使其比"私有"更加隐蔽。这类似于为什么你不能在interface IA { ... }
中使用public
编辑后
完全不同的情况:
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
你可以有一个内部(甚至一个私有(属性,以及一个公开它的显式接口实现:
public class Foo : ITest1
{
internal Poco Obj { get; set; }
Poco ITest1.Obj { get { return Obj; } set { Obj = value; } }
}
这是"更改"接口成员可见性的推荐方法。许多 .NET 类使用此技术将接口成员转换为protected virtual
成员。
这就是规范中定义显式接口的方式。
">显式"部分意味着"我会告诉代码何时将该对象视为接口",因此除非您告诉代码(通过强制转换(,否则它不会看到接口的方法/属性。如果您有两个接口具有同名的方法,这将非常有用。
你可以有一个内部接口,但你不能把它用于公共类(请参阅这篇文章了解一些原因(。
下面是一个有效实现的示例:
internal interface IKeyable
{
int ID {get; set;}
}
internal class MyClass: IKeyable
{
public int ID { get; set; }
}
关于问题编辑:
有几件事不适用于这种情况:
Foo
类的Obj
属性(默认情况下(是私有的,因此无论有没有接口,都无法访问类外部。- 由于接口中定义的所有成员都必须可从类外部访问,因此
Obj
不被视为实现ITest1
接口的合适候选项。 - 虽然
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;}
}
您的属性仍然缺少类型。即使要将其声明为接口成员的显式实现,仍需要指定类型。
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 指定访问修饰符,这使它成为私有的。