访问所有者类中的内部接口

本文关键字:内部 接口 所有者 访问 | 更新日期: 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; }
}

关于问题编辑:

有几件事不适用于这种情况:

  1. Foo类的 Obj 属性(默认情况下(是私有的,因此无论有没有接口,都无法访问类外部。
  2. 由于接口中定义的所有成员都必须可从类外部访问,因此Obj不被视为实现ITest1接口的合适候选项。
  3. 虽然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 指定访问修饰符,这使它成为私有的。