繁体   English   中英

如何使公共类从私有接口继承,而不会出现不一致的可访问性错误

[英]How to have a public class inherit from private interface, without getting Inconsistent accessibility error

这是我要做什么的解释:

public class MyClass
{
  public T GetFoo<T>() : where T : class, MyInterface
  {
    if (typeof(T) == typeof(Class1)
    {
      return new Class1() as T;
    }
    else if (typeof(T) == typeof(Class2))
    {
      return new Class2() as T;
    }
    else
    {
      return default(T);
    }
  }

  private interface MyInterface {}  // This is actually empty, it doesn't do anything except limit the types that can be passed to GetFoo()

  public class Class1 : MyInterface
  {
    // Stuff
  }

  public class Class2 : MyInterface
  {
    // Other Stuff
  }
  // there are many more such classes that all inherit from MyInterface
}

因此,我有一个使用公共方法的公共课程。 该方法接受通用类型参数。 但是我想限制它接受的T的类型,所以这就是为什么它使用MyInterface的原因。 当然,由于MyInterface是私有的,因此无法编译。 它将引发“不一致的可访问性:约束类型的访问性少于”错误。

但是,这就是我希望它以这种方式工作的原因:

Class1,Class2等中的每一个都声明为公共,以便其他人可以使用它们。 但是我想限制其他人不能声明自己的此类并将其传递给GetFoo()方法。 因为那会破坏GetFoo(),所以这就是为什么我希望MyInterface私有。

如果我将MyInterface公开,那么它当然会编译,并且一切都会正常进行。 但是我需要能够防止其他人声明自己的类并继承MyInterface并将其传递给GetFoo()。

我想允许呼叫者这样做:

Class1 userFoo = GetFoo<Class1>();

我想防止呼叫者这样做:

Class UserClass : MyInterface {}
...
UserClass userFoo = GetFoo<UserClass>();

编辑:感谢所有非常快速的答复。 是的,我知道这不是接口的目的,在当时对我来说似乎很有意义。 如果存在的话,我当然愿意寻求更优雅的解决方案。

你不能。 从根本上讲这是不可能的。 通过将接口private ,调用者实际上不知道类是否实现了该接口。 但是通过在类型约束中使用它,您确实需要调用者知道类是否实现了该接口。


您可以做的是使用一个通用的基类:即使该基类必须是public ,您也可以防止其他人从该基类派生。

public class Base {
  internal Base() { }
}
public interface IBase { }
public sealed class Class1 : Base, IBase {
  ...
}
public sealed class Class2 : Base, IBase {
  ...
}
public T GetFoo<T>() where T : Base, IBase {
  ...
}

IBase接口用于确保GetFoo<Base>将被拒绝。 sealed Class1Class2 ,以防止其他人从这些派生。

但是,只有在Class1Class2具有共同的基类的情况下,此方法才有效。


不过,我鼓励您重新考虑您的设计。 几乎总是,如果您的通用代码具有一堆typeof(T) == typeof(SomeConcreteClass)条件,这强烈表明您最好为每种具体类型创建单独的方法。 但是也有例外,我不排除您的代码是例外之一的可能性。

创建一个实现接口的类并尝试隐藏该接口提供给您的抽象完全没有任何意义。

面向对象不是针对对象进行编程,而是要针对接口编程,而是要隐藏它们。

最好考虑使用其他方法。

该代码可以工作并编译:

public class MyClass<T> where T : class, IMyInterface
{
    public T GetFoo()
    {
        if (typeof (T) == typeof (Class1))
        {
            return new Class1() as T;
        }
        else if (typeof (T) == typeof (Class2))
        {
            return new Class2() as T;
        }
        else
        {
            return default(T);
        }
    }
}

public interface IMyInterface {}  // This is actually empty, it doesn't do anything except limit the types that can be passed to GetFoo()

public class Class1 : IMyInterface
{
// Stuff
}

public class Class2 : IMyInterface
{
// Other Stuff
}
// there are many more such classes that all inherit from MyInterface

和主要方法工作正常:

    static void Main(string[] args)
    {
        var a1 = new MyClass<Class1>();
        var a2 = a1.GetFoo();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM