C# 如何访问嵌套泛型类上的方法/接口

C# 如何访问嵌套泛型类上的方法/接口,c#,class,generics,nested-generics,C#,Class,Generics,Nested Generics,我需要嵌套泛型,如A

我需要嵌套泛型,如A

当我这样做时,只有外部属性(A)被暴露。我不知道如何访问(B)的方法等。然后我尝试在内部使用相同的结果访问接口

(编辑)为了澄清用例,我需要的解决方案应该可以使用 公共C类:A>或 公共类C:B> 我不需要它们来生成相同的类,但这两个定义都有相应的方法。正如您可能怀疑的那样,我正试图使用它在多个对象之间以模块化模式实现公共功能。扩展方法让我很接近,但它们不会像这个解决方案那样(如果可以实现的话)允许重写行为

我附带了测试代码,它可能比我所能理解的更清楚地显示了问题

using System;
using System.Reflection;

namespace ArchitecturalTestGround
{
    public interface IBase
    {
        void BaseMethod1();
    }
    public interface IA : IBase
    {
        void AMethod();
    }
    public interface IB : IBase
    {
        void BMethod();
    }
    public class Base : IBase
    {
        public void BaseMethod1() { }
    }
    public class A<T> : IA where T : IBase
    {
        public void BaseMethod1() { }
        public void AMethod() { }
    }
    public class B<T> : IB where T : IBase
    {
        public void BaseMethod1() { }
        public void BMethod() { }
    }
    public class Test1 : A<B<Base>>
    {
    }

    public class Test2 : B<A<Base>>
    {
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Test1 e1 = new Test1();
            Test2 e2 = new Test2();


            Console.WriteLine("Test1 - A<B<Base>>");
            foreach (MemberInfo mi in typeof(Test1).GetMembers())
            {
                Console.WriteLine($"  {mi.Name}.{mi.MemberType}");
            }
            if (e1 is IB) { Console.WriteLine("   Supports IB"); }
            if (e1 is IA) { Console.WriteLine("   Supports IA"); }

            Console.WriteLine();
            Console.WriteLine("Test2 - B<A<Base>>");
            foreach (MemberInfo mi in typeof(Test2).GetMembers())
            {
                Console.WriteLine($"  {mi.Name}.{mi.MemberType}");
            }
            if (e2 is IB) { Console.WriteLine("   Supports IB"); }
            if (e2 is IA) { Console.WriteLine("   Supports IA"); }

            Console.ReadKey();
        }
    }
}
使用系统;
运用系统反思;
命名空间体系结构altestground
{
公共接口IBase
{
void BaseMethod1();
}
公共接口IA:IBase
{
无效方法();
}
公共接口IB:IBase
{
无效b方法();
}
公共类基:IBase
{
public void BaseMethod1(){}
}
公共A类:IA,其中T:IBase
{
public void BaseMethod1(){}
公共无效AMethod(){}
}
公共类B:IB,其中T:IBase
{
public void BaseMethod1(){}
public void BMethod(){}
}
公共类Test1:A
{
}
公共类Test2:B
{
}
公共课程
{
公共静态void Main(字符串[]args)
{
test1e1=新的Test1();
test2e2=新的Test2();
Console.WriteLine(“Test1-A”);
foreach(typeof中的MemberInfo mi(Test1.GetMembers())
{
WriteLine($“{mi.Name}.{mi.MemberType}”);
}
如果(e1是IB){Console.WriteLine(“支持IB”);}
如果(e1是IA){Console.WriteLine(“支持IA”);}
Console.WriteLine();
控制台写入线(“Test2-B”);
foreach(typeof中的MemberInfo mi(Test2.GetMembers())
{
WriteLine($“{mi.Name}.{mi.MemberType}”);
}
如果(e2是IB){Console.WriteLine(“支持IB”);}
if(e2是IA){Console.WriteLine(“支持IA”);}
Console.ReadKey();
}
}
}

Test1
继承自
A
(无论
T
是什么),而
A
继承自
IA
,后者又继承自
IBase
,因此您只能看到该继承链中的方法:

A

IA

void AMethod();
IBase

void BaseMethod1();
(顺便说一句,从代码示例中注意,由于BaseMethod1,您可能会收到编译器警告)

我想我明白你的意思了。您可能遇到了需要从两个类继承的情况。在C#中不可能有多类继承。不过,有一些方法可以解决这个问题

一般来说,如果你遇到这样的情况,很多时候这意味着你需要重新考虑你的设计。如果你仍然对这个话题感兴趣,那么看看这个家伙:


可以这样更改您的定义吗

public class A<T> : IA where T : IBase
{
    T NestedGeneric;

    public A(T nested)
    {
        NestedGeneric = nested;
    }

    public void BaseMethod1() { }

    public void AMethod() { }
}


public class Test1 : A<B<Base>>
{
    public B<Base> NestedGeneric;
    public Test1(B<Base> nested) : base(nested)
    {
        NestedGeneric = nested;
    }
}
公共类A:IA,其中T:IBase
{
T NestedGeneric;
公共A(T嵌套)
{
NestedGeneric=嵌套;
}
public void BaseMethod1(){}
公共无效AMethod(){}
}
公共类Test1:A
{
公共B类;
公共Test1(B嵌套):基(嵌套)
{
NestedGeneric=嵌套;
}
}

这允许您执行
e1.NestedGeneric.BMethod()

看一看
type.GetGenericArguments()
。我要去的地方你说得对!我在我的问题中添加了一些评论,以帮助进一步解释这一点。然而,我不相信多重继承总是不好的。它很强大,可以被误用,但这并不意味着它在所有情况下都不合适。(明显避免了陈词滥调)我没说这很糟糕。我只是说了大部分时间。:-)顺便说一下,你误解了泛型。将泛型类型与其他类类型结合使用只会帮助您创建一个模板,您可以在其中使用该类型,但它不会将定义合并到基类中。也就是说,除非您决定使用内部实例将调用转发给.Juan-接受批评。一部分原因是我误解了,另一部分原因是我不愿意在没有解决办法的情况下接受事实好主意,我还测试了一个。然而,这并不能让我达到目的。我在上面添加了一些评论,以澄清我的意图。
public class A<T> : IA where T : IBase
{
    T NestedGeneric;

    public A(T nested)
    {
        NestedGeneric = nested;
    }

    public void BaseMethod1() { }

    public void AMethod() { }
}


public class Test1 : A<B<Base>>
{
    public B<Base> NestedGeneric;
    public Test1(B<Base> nested) : base(nested)
    {
        NestedGeneric = nested;
    }
}