C# 在类中存储不同泛型类型的列表

C# 在类中存储不同泛型类型的列表,c#,list,class,generics,dynamic,C#,List,Class,Generics,Dynamic,我附上了一张我想做的事情的照片。假设我在一个班级里有一个T的列表 public class MyClass<T> where T : IMyInterface { public List<T> list = new List<T>; } 公共类MyClass 其中T:IMyInterface { 公共列表=新列表; } 现在,另一个类有MyClass的列表 public class AnotherClass { public Li

我附上了一张我想做的事情的照片。假设我在一个班级里有一个T的列表

public class MyClass<T> 
    where T : IMyInterface
{
    public List<T> list = new List<T>;
}
公共类MyClass
其中T:IMyInterface
{
公共列表=新列表;
}
现在,另一个类有MyClass的列表

public class AnotherClass
{
    public List<MyClass<IMyInterface>> list = new List<MyClass<IMyInterface>>;
}
公共类另一类
{
公共列表=新列表;
}
我应该为我的班级写什么T?如果我输入T,那么它假设该类中的所有类型都是相同的,但事实并非如此。如果我使用IMyInterface,在访问这些类时就不能将IMyInterface转换为t

new AnotherClass().list.Add(new MyClass<T>()); 
newanotherclass().list.Add(newmyclass());

现在这里是什么类型的?另一个类泛型类型中的列表是IMyInterface,但我要添加的东西是T,我希望它是动态的,但它们仍然在IMyInterface下。

泛型中的
T
在其整个生命周期中必须是相同的

例如

var a = new MyClass<int>();
a.list.Add(1); //since a's generic T is declared as int the list is now also int

var b = new MyClass<string>()
b.list.Add("string"); //in b its now declared as a string and avccepts only string
下面是我在ConsoleApplication中制作的一个示例,展示了它是如何布局的

public class MyClass<T> where T : IMyInterface
{
    public List<T> list = new List<T>();
}
public interface IMyInterface
{
}
public class Foo : IMyInterface
{
}
public class Bar : IMyInterface
{
}
public class FooBar
{
    public void Test()
    {
        var content = new MyClass<IMyInterface>();
        content.list.Add(new Foo());
        if (content.list[0] is Foo)
        {
            //Execute on Foo 
            var g = (Foo)content.list[0];
            //Now you can access Foo's methods and not only the Interfaces
            Console.WriteLine("Foo");
        }
        else if (content.list[0] is Bar)
        {
            //Execute on Bar
            var g = (Bar)content.list[0];
            //Now you can access Bar's methods and not only the Interfaces
            Console.WriteLine("Bar");
        }
    }
}
公共类MyClass其中T:IMyInterface
{
公共列表=新列表();
}
公共接口IMyInterface
{
}
公共类Foo:IMyInterface
{
}
公共类酒吧:IMyInterface
{
}
公共级FooBar
{
公开无效测试()
{
var content=new MyClass();
content.list.Add(newfoo());
if(content.list[0]是Foo)
{
//在Foo上执行
var g=(Foo)content.list[0];
//现在您可以访问Foo的方法,而不仅仅是接口
Console.WriteLine(“Foo”);
}
else if(内容列表[0]为条形图)
{
//在吧台上执行
var g=(Bar)content.list[0];
//现在您可以访问Bar的方法,而不仅仅是接口
控制台写入线(“Bar”);
}
}
}

我认为您的意思是希望在一个列表中包含多个泛型类型,例如:

var ac = new AnotherClass();
ac.list.Add(new MyClass<int>()); 
ac.list.Add(new MyClass<bool>()); 
ac.list.Add(new MyClass<double>());
限制可以添加的内容的唯一方法是使用抽象基类

public class MyClassBase 
{

}
public class MyClass<T> : MyClassBase
    where T : IMyInterface
{
    public List<T> list = new List<T>();
}
公共类MyClassBase
{
}
公共类MyClass:MyClassBase
其中T:IMyInterface
{
公共列表=新列表();
}
然后列出以下各项:

public class AnotherClass
{
    public List<MyClassBase> list = new List<MyClassBase>();
}
公共类另一类
{
公共列表=新列表();
}

在访问这些对象时,您仍然需要进行一些类型检查,但至少您会知道这些对象仅限于继承MyClassBase的对象。我认为您的问题是,您不需要为此使用泛型。如果将类指定为:

public class MyClass
{
    public IList<IMyInterface> list = new List<IMyImterface>();
}
使用

公共接口IMyInterface{}
公共A类:IMyInterface{}
公共类B:IMyInterface{}
//协变界面
公共接口IMyClass{}
//继承IMyClass
公共类MyClass:IMyClass,其中T:IMyInterface
{ 
公共列表=新列表();
}
公共类另一类
{
//注意使用IMyClass而不是具体的MyClass类型的列表
//协变接口类型将允许任何imy接口转换
公共列表=新列表();
公共另一类()
{
this.list.Add(new MyClass());
this.list.Add(new MyClass());
}
}

问题在于您描述的是问题的解决方案,而不是实际问题。你想解决什么问题。我已经有一段时间没有使用c#了,但我不会使用泛型。如果您知道只在其中放置实现接口的对象,为什么不使用“变形”。这意味着:公共列表=新列表;你似乎把事情搞糊涂了。泛型不是动态类型的。C#中的所有内容都是静态类型的,除了涉及
dynamic
关键字的语句/声明,但这与泛型无关。
List
是仅包含
int
s的列表<代码>列表是一个仅包含实现
IMyInterface
的对象的列表。从序列中获取特定子类型的所有实例的标准方法是
seq.OfType()
(您的版本执行两次类型检查)。尽管你不应该对100个案例中的99个进行贬低,谢谢你的提示。我希望这会更快?我假设时间复杂度是相同的,但我不会真的担心性能,两者都足够快,永远不会成为应用程序的瓶颈。说你想要什么,而不是说应该做什么,因为你知道这会导致你想要的,这更干净。这是一种声明性的东西,而不是命令性的东西。@SteveHarris我认为cast
(DummyClass)项将抛出一个异常,而不是返回null。它应该是
项,因为DummyClass
c.list[0]是dd1
。这使得dd1的子类可以用dd1的代码来处理。@Taemyr
is
是一个bool求值器(我可能用它来代替
GetType/typeof
。你是否认为
(接近强制转换,但允许结果为
null
)我的意思是代替GetType().在你的例子中,使用as是没有意义的。是的,使用
是这样的,会使它更好一点,因为它是一种语法糖。
list.Add(1); 
list.Add("hello"); 
public class MyClassBase 
{

}
public class MyClass<T> : MyClassBase
    where T : IMyInterface
{
    public List<T> list = new List<T>();
}
public class AnotherClass
{
    public List<MyClassBase> list = new List<MyClassBase>();
}
public class MyClass
{
    public IList<IMyInterface> list = new List<IMyImterface>();
}
public class DummyClass : IMyInterface {}

public class AnotherClass {
{
    IList<MyClass> anotherList = new List<MyClass>();

    public void AMethod()
    {
        MyClass myList = new MyClass();
        myList.Add(new DummyClass());

        anotherList.Add(myList);
    }
}
foreach (IMyImterface item in myList.Where(x => x is DummyClass))
{
    DummyClass dummy = (DummyClass)item;
}

// or
foreach (IMyImterface item in myList.OfType<DummyClass>())
{
    DummyClass dummy = (DummyClass)item;
}
foreach (IMyIntetface item in myList)
{
    DummyClass dummy = item as DummyClass;
    if (dummy != null)
    {
        // do something
    }
}
public interface IMyInterface { }
public class A : IMyInterface { }
public class B : IMyInterface { }

// Covariant interface
public interface IMyClass<out T> { }

// Inherit IMyClass
public class MyClass<T> : IMyClass<T> where T : IMyInterface 
{ 
    public List<T> list = new List<T>(); 
}

public class AnotherClass
{
    // Note the list using IMyClass instead of the concrete MyClass type
    // The covariant interface type would allow any IMyInterface conversion
    public List<IMyClass<IMyInterface>> list = new List<IMyClass<IMyInterface>>();

    public AnotherClass()
    {
        this.list.Add(new MyClass<A>());
        this.list.Add(new MyClass<B>());
    }
}