使用泛型类型或接口的 C# 集合

发布于 2024-09-14 18:09:31 字数 1206 浏览 5 评论 0原文

我有一组实现接口 (IMyClass) 的类 (MyClass1、MyClass2、MyClass3)。

我有兴趣创建一个方法来填充和返回具有公共接口 MyClass的对象列表 (Collection.Generics.Lists) XList)。但如何呢?

每个类都有一个构造函数 MyClassX ,它执行不同的操作。所以我无法创建一个BaseClass并为所有人使用一个通用的构造函数。

通过接口我不能这样做:

public List<IMyClass> Fill(string[] ItemsPassedByParam, IMyClass InstanceOfMyClassX)
    List MyList = new List<IMyClass>();
    foreach (item in ItemsPassedByParam)
    {
        MyList.Add (new IMyClass (item)); //can't do new from an Interface!!
    }
}

我还尝试在下一个示例中使用泛型类型 TMyClass,但这对我来说都不起作用(尽管我对泛型类型没有很深的概念):

public List<TMyClass> Fill(string[] ItemsPassedByParam, Type TypeOfMyClassX)
    List MyList = new List <TMyClass> ();
    foreach (item in ItemsPassedByParam)
    {
        MyList.Add (new TMyClass (item)); //can't do new from a Generic Type!!
    }
}

我还尝试将构造函数内的代码外部化MyClassX 在一个方法中,但我无法调用该方法,因为 de 对象未初始化(没有 new ( ))。

在这些情况下,哪个是解决方案?

提前致谢!

I have a set of classes (MyClass1, MyClass2, MyClass3) that implement an interface (IMyClass).

I am interested in creating a method to fill and return a list (Collection.Generics.Lists<>) of objects that have common interface MyClassX (List<IMyClass>). But how?

Each class has a constructor MyClassX which does something different. So I can not create a BaseClass and use a common constructor for all.

By interface I can not do:

public List<IMyClass> Fill(string[] ItemsPassedByParam, IMyClass InstanceOfMyClassX)
    List MyList = new List<IMyClass>();
    foreach (item in ItemsPassedByParam)
    {
        MyList.Add (new IMyClass (item)); //can't do new from an Interface!!
    }
}

Also I tried using generics type, TMyClass in the next example, but neither has worked for me (though I have not very deep notions about generic types):

public List<TMyClass> Fill(string[] ItemsPassedByParam, Type TypeOfMyClassX)
    List MyList = new List <TMyClass> ();
    foreach (item in ItemsPassedByParam)
    {
        MyList.Add (new TMyClass (item)); //can't do new from a Generic Type!!
    }
}

I tried also to externalize the code inside the Constructor of MyClassX in a method, but I can't call the method since de object is not initialized (there is no new () ).

In these cases which is the solution?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

找回味觉 2024-09-21 18:09:31

听起来您希望 Fill 方法从传入的字符串值创建 List ,其中 TIMyClass 的派生。

您需要做的是将工厂函数传递到 Fill 方法中,该方法允许创建 IMyClass 派生实例。

public List<IMyClass> Fill(
  string[] ItemsPassedByParam, 
  Func<string,IMyClass> createFunc)

  List MyList = new List<IMyClass>();
  foreach (item in ItemsPassedByParam) {
    MyList.Add(createFunc(item));        
  }
}

然后在调用 Fill 的地方可以选择要使用的 IMyClass 派生

string[] items = ...;
List<IMyClass> list1 = Fill(items, item => new MyClass1(item));
List<IMyClass> list2 = Fill(items, item => new MyClass2(item));

It sounds like you want the Fill method to create a List<T> from the passed in string values where T is a derivation of IMyClass.

What you need to do is pass a factory function into the Fill method which allows for the creation of IMyClass derived instances.

public List<IMyClass> Fill(
  string[] ItemsPassedByParam, 
  Func<string,IMyClass> createFunc)

  List MyList = new List<IMyClass>();
  foreach (item in ItemsPassedByParam) {
    MyList.Add(createFunc(item));        
  }
}

Then at the place you call Fill you can choose which derivation of IMyClass to use

string[] items = ...;
List<IMyClass> list1 = Fill(items, item => new MyClass1(item));
List<IMyClass> list2 = Fill(items, item => new MyClass2(item));
撞了怀 2024-09-21 18:09:31

这里最好的选择是创建一个 IMyClassFactory 来处理参数的获取、确定要构造的具体类型、调用构造函数并返回它:

public class IMyClassFactory
{
    public static IMyClass CreateInstance(string item)
    {
        switch(item)
        {
            case "SomeValue":
            case "SomeValue2":
                return new MyClass1(item);
            case "SomeOtherValue":
                return new MyClass2(item);
        }
    }
}

该工厂显然假设您可以从传递到工厂的字符串推断类型。很可能情况并非如此,在这种情况下,您需要添加另一个参数,以允许您推断要实例化的具体类型。

一旦你有了工厂,那么你就可以让你的原始方法使用工厂:

public List<IMyClass> Fill(string[] ItemsPassedByParam)
{
    List MyList = new List<IMyClass>();

    foreach (item in ItemsPassedByParam)
    {
        MyList.Add(IMyClassFactory.CreateInstance(item));
    }
}

The best option here is to create a IMyClassFactory that handles taking the parameter, figuring out which concrete type to construct, call the constructor, and return it:

public class IMyClassFactory
{
    public static IMyClass CreateInstance(string item)
    {
        switch(item)
        {
            case "SomeValue":
            case "SomeValue2":
                return new MyClass1(item);
            case "SomeOtherValue":
                return new MyClass2(item);
        }
    }
}

That factory obviously assumes that you can infer type from the string being passed in to the factory. There's a good chance that isn't the case, in which case you need to add another parameter that allows you to infer the concrete type to instantiate.

Once you have the factory, then you can make your original method use the Factory:

public List<IMyClass> Fill(string[] ItemsPassedByParam)
{
    List MyList = new List<IMyClass>();

    foreach (item in ItemsPassedByParam)
    {
        MyList.Add(IMyClassFactory.CreateInstance(item));
    }
}
望她远 2024-09-21 18:09:31

不能创建接口的实例,但可以创建泛型类型的实例 - 前提是它具有默认构造函数。然后,您可以将项目传递给实例的属性或方法,而不是使用构造函数注入。

public List<TMyClass> Fill(string[] ItemsPassedByParam) 
    where TMyClass : IMyClass, new() {
    ...
        IMyClass inst = new TMyClass();
        inst.SetItem(item);
        myList.Add(inst);
    ...
}

调用 new TMyClass 与调用 Activator.CreateInstance() 具有相同的效果。泛型 CreateInstance 不允许将参数传递给构造函数,但您可以传递它们使用非通用 CreateInstance。

public List<TMyClass> Fill(string[] ItemsPassedByParam) {
    ...
        myList.Add((IMyList)Activator.CreateInstance(typeof(TMyClass), item));
    ...
}

You cannot create an instance of an interface, but you can create an instance of a generic type - provided it has a default constructor. you can then pass the item to the instance to a property or method rather than using constructor injection.

public List<TMyClass> Fill(string[] ItemsPassedByParam) 
    where TMyClass : IMyClass, new() {
    ...
        IMyClass inst = new TMyClass();
        inst.SetItem(item);
        myList.Add(inst);
    ...
}

Calling new TMyClass has the same effect as calling Activator.CreateInstance<TMyClass>() The generic CreateInstance does not allow arguments to be passed to the constructor, but you can pass them with a non-genric CreateInstance.

public List<TMyClass> Fill(string[] ItemsPassedByParam) {
    ...
        myList.Add((IMyList)Activator.CreateInstance(typeof(TMyClass), item));
    ...
}
み格子的夏天 2024-09-21 18:09:31

也许这里直接使用工厂模式就可以了,就看你如何判断需要哪种类型了。

也许您需要使用反射并调用 ConstructorInfo (将参数传递给构造函数,返回一个对象,有利于在模板方法中构建,但也有利于在运行时进行爆炸,当您执行相当于在编译时捕获)。

后者似乎最接近您一直在尝试的方法,尽管如果您可以从类型更安全的工厂中执行操作,那么这可能就是要走的路。

public static T BuildOne(SomeParamType myParam)
{
  ConstructorInfo constrInfo = typeof(T).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[]{typeof(SomeParamType)}, null);
  return (T)constrInfo.Invoke(new object[]{myParam});
}

Maybe you can just use the factory pattern here, depending on how you judge which type is needed.

Maybe you'll need to use reflection and invoke a ConstructorInfo (passes parameters to a constructor, returns an object, good for building in template methods, but also good for blowing up in run-time when you do the equivalent of something that would be caught at compile-time).

The latter seems closest to what you've been trying, though if you can just do things from a more type-safe factory then that's probably the way to go.

public static T BuildOne(SomeParamType myParam)
{
  ConstructorInfo constrInfo = typeof(T).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[]{typeof(SomeParamType)}, null);
  return (T)constrInfo.Invoke(new object[]{myParam});
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文