Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何访问子体对象';C语言中的s内部方法#_C#_Inheritance_Internal - Fatal编程技术网

C# 如何访问子体对象';C语言中的s内部方法#

C# 如何访问子体对象';C语言中的s内部方法#,c#,inheritance,internal,C#,Inheritance,Internal,我试图访问从同一父类继承的对象中的父类(在其自己的程序集中)中标记为内部的方法 让我解释一下我想做什么 我想创建一个服务类,将带有基础列表的IEnumerable返回给非服务类(例如UI),并可以选择将带有基础IQueryable的IEnumerable返回给其他服务 我编写了一些示例代码来演示我试图实现的目标,如下所示。这个例子不是真实的生活,所以在评论时请记住这一点 所有服务都将继承如下内容(仅显示相关代码): 公共类ServiceBase { 受保护的只读ObjectContext\u上下

我试图访问从同一父类继承的对象中的父类(在其自己的程序集中)中标记为内部的方法

让我解释一下我想做什么

我想创建一个服务类,将带有基础列表的IEnumerable返回给非服务类(例如UI),并可以选择将带有基础IQueryable的IEnumerable返回给其他服务

我编写了一些示例代码来演示我试图实现的目标,如下所示。这个例子不是真实的生活,所以在评论时请记住这一点

所有服务都将继承如下内容(仅显示相关代码):

公共类ServiceBase
{
受保护的只读ObjectContext\u上下文;
受保护字符串_setName=string.Empty;
公共服务库(ObjectContext上下文)
{
_上下文=上下文;
}
公共IEnumerable GetAll()
{
返回GetAll(false);
}
//这些不是正确的访问修饰符..我需要一些东西
//子类和子类之间可以访问的
内部保护IEnumerable GetAll(布尔返回查询)
{
var query=_context.CreateQuery(GetSetName());
如果(返回可查询)
{
返回查询;
}
其他的
{
返回query.ToList();
}
}
私有字符串GetSetName()
{
//一些代码。。。
返回_setName;
}
}
继承的服务如下所示:

public class EmployeeService : ServiceBase<Employees>
{
    public EmployeeService(ObjectContext context)
        : base(context)
    {

    }

}

public class DepartmentService : ServiceBase<Departments>
{
    private readonly EmployeeService _employeeService;

    public DepartmentService(ObjectContext context, EmployeeService employeeService) : base(context)
    {
        _employeeService = employeeService;
    }

    public IList<Departments> DoSomethingWithEmployees(string lastName)
    {
        //won't work because method with this signature is not visible to this class
        var emps = _employeeService.GetAll(true);

        //more code...
    }
}
公共类EmployeeService:ServiceBase
{
公共EmployeeService(ObjectContext上下文)
:基本(上下文)
{
}
}
公共类部门服务:ServiceBase
{
私人只读员工服务(U EmployeeService);
公共部门服务(ObjectContext上下文,EmployeeService EmployeeService):基础(上下文)
{
_employeeService=employeeService;
}
公共IList DoSomethingWithEmployees(字符串lastName)
{
//无法工作,因为具有此签名的方法对此类不可见
var emps=_employeeService.GetAll(true);
//更多代码。。。
}
}
因为父类是可重用的,所以它将位于与子服务不同的程序集中。如果将GetAll(bool returnQueryable)标记为internal,则子对象将无法看到彼此的GetAll(bool)方法,而只能看到public GetAll()方法

我知道我可以向每个服务(或者同一程序集中的中间父类)添加一个新的内部GetAll方法,以便程序集中的每个子服务都可以看到彼此的方法;但它似乎没有必要,因为该功能在父类中已经可用

例如:

    internal IEnumerable<Employees> GetAll(bool returnIQueryable)
    {
        return base.GetAll(returnIQueryable);
    }
内部IEnumerable GetAll(bool returnIQueryable)
{
return base.GetAll(returnIQueryable);
}
本质上,我希望服务能够以IQueryable的形式访问其他服务方法,这样它们就可以进一步细化未提交的结果,而其他所有人都可以得到普通的旧列表

有什么想法吗

编辑

你知道吗,我玩得很开心,玩了一点密码高尔夫。。。但最终我还是不能使用这个方案,因为我传递的是接口,而不是类

因此,在我的示例中,GetAll(boolreturniqueryable)不在接口中,这意味着我必须进行强制转换,这与我试图实现的目标背道而驰


我不确定我是否有大脑放屁,或者我只是太兴奋了,想得到一些我认为很好用的东西。不管怎样,谢谢你的回答。

公开这个方法的明显答案有什么不对

可访问性无论如何都是不安全的,所以“邪恶的人”可以使用反射来绕过您所使用的任何修改器。由于您希望从不相关的“同级”类调用这些方法,它们应该是公共的,因为没有“同级”可访问性修饰符

备选建议:应用
[assembly:InternalsVisibleTo(“SomeOtherAssembly”)]
属性授予其他业务域程序集对内部成员的访问权限


请注意,这会增加维护负担(如果重命名或添加程序集),使用“魔术字符串”,并否定内部的原始含义(因为所有内部成员现在也将对这些其他程序集可见)。

如果您的子类将位于同一程序集中,这将更容易。但是,当类位于单独的程序集中时(将接口的
internal
关键字更改为
public
),以下“技巧”也会起作用,但它只会阻止在不强制转换对象时调用该方法。例如,将
InheritedClass
对象强制转换为
IBaseInterface
将允许任何人调用
GetValue
方法。这是你无法真正阻止的,因为即使有一些关键字组合可以做你想做的事情,也有人可以通过反射来调用这些方法

internal interface IBaseInterface {
    string GetValue();
}

public abstract class MyBase : IBaseInterface {
    string IBaseInterface.GetValue()
    { return "MyBase"; }
}

public class InheritedClass : MyBase {
    public void PrintValue(IBaseInterface someclass)
    { Console.WriteLine(someclass.GetValue()); }
}

也许我遗漏了一些东西,但您应该能够将其标记为
受保护的内部
,并实现您的目标

namespace Foo
{
    class A
    {
        protected internal void D() { Console.WriteLine(this.ToString() + " says 'Blah'"); }
    }
}

namespace Bar
{
    class B : Foo.A 
    {
        public B()
        {
        }
    }
}

namespace Baz
{
    class C : Foo.A
    {
        public C()
        {
            D();
            Bar.B b = new Bar.B();
            b.D();

            Foo.A a = new Foo.A();
            a.D();
        }
    }
}
查看输出

Baz.C c = new Baz.C();
这都是法律法规。Foo.A是基础,Bar.B和Baz.C继承自Foo.A。void D是a.Baz.C的一个受保护的内部成员,它可以按预期调用D(),也可以创建Bar.B和Foo.a的实例并调用它们的D()方法

受保护的内部
成员对任何程序集中的所有子类以及作为基的同一程序集中的所有类都可见。可访问性在这些边界之外结束。与子类位于同一程序集中的非子类将无法看到成员。

我不是想对“邪恶的人”隐藏,我们的策略是业务层应将列表返回到上面的l
Baz.C c = new Baz.C();