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

时间:2013-10-08 07:43:02

标签: c#

我有一个内部界面。通常我使用公共接口,但这次我在内部保留了很多东西。

现在问题是当我在一个实现内部接口的公共类中时,内部成员的容器为什么我不能在不进行转换(显式实现)的情况下访问接口成员?我在“所有者”类中,实现接口的类,完全在里面,我应该拥有所有权利,对吗?

我不介意如果我只在代码中使用一次,但事实并非如此。我在代码中有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;
    }
}

4 个答案:

答案 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; }
}

关于编辑问题:

有几件事情不适合这种情况:

  1. Obj类的Foo属性(默认情况下)是私有的,因此无论是否有接口,它都无法在类外访问。
  2. 由于界面中定义的所有成员必须才能从课程外部访问,因此Obj不被视为ITest1实施的合适人选1}} interface。
  3. 虽然Foo是公开的,但Poco是内部的,这意味着即使用户(从程序集外部将能够访问该类,他也无法访问该属性,这没有意义。
  4. 如果你想向世界公开一个内部类(例如,暴露它的数据,但不是它的内部细节),你可以创建一个公共访问接口,或者创建一个知道要转换的公共访问类来自你的班级。

    所以你可以这样做:

    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指定访问修饰符,这使其成为私有。