C# - 如何将类型作为参数传递

时间:2010-12-06 20:49:32

标签: c# .net types

我认为提问比回答问题更难。 我想用一个例子问我的问题: 您知道我们可以将对象绑定到DataSource,并且该对象可以是任何类型。因此,假设我已将“MyClass”类型的对象绑定到DataSet的DataSource。 现在我将此数据集作为参数发送到另一个DLL中的另一个类,并且在此DLL文件中,我想创建一个List<>类型为“MyClass”。 由于我无法访问“MyClass”类型,我可以使用此代码来获取DataSource的类型:

_dataSet.DataSource.GetType()

但我无法使用以下代码创建“MyClass”类型的List: List<_dataSet.DataSource.GetType()> _list;

在这种情况下我该怎么做?

5 个答案:

答案 0 :(得分:1)

基本上有两种选择:

  1. 坚持List<object>或者更好,我们最近的已知祖先类型_dataSet.DataSource
  2. 或使用讨厌的反射黑客动态实例化List<T>
  3. 在大多数情况下,我个人会使用选项(1),因为它是:

    • 更易于使用,
    • 可读,
    • 足够安全,
    • 在自然代码重用方面具有普遍性。

    第二个选项已在其他答案中详细阐述。

答案 1 :(得分:0)

var newtype = typeof (List<>).MakeGenericType(_dataSet.DataSource.GetType());
var _list = Activator.CreateInstance(newtype);

答案 2 :(得分:0)

您可以使用反射动态创建泛型类型:

var listType = typeof(List<>).MakeGenericType(
    new[] { _dataSet.DataSource.GetType() }
);
var ctor = listType.GetConstructor(new Type[] { });
var list = ctor.Invoke(null);

请注意,list将被输入为object

答案 3 :(得分:0)

您需要使用反射来实例化所需类型的通用列表。这种方法可以解决这个问题:

public object InstantiateGenericList( Type nodeType )
{
    Type   list        = typeof(List<>) ;
    Type   genericList = list.MakeGenericType( nodeType ) ;
    object instance    = Activator.CreateInstance( genericList ) ;

    return instance ;
}

答案 4 :(得分:0)

你可以使用反思,正如其他答案所指出的那样。

您是否可以控制其他DLL中的其他类?你可以让那个类或你在该类上调用的特定方法通用吗?

public class SomeOtherClassInSomeOtherDLL
{
    public void DoSomethingWithData<T>(T dataSource)
    {
        // ...

        List<T> list = new List<T>();
        list.Add(dataSource);

        // ...
    }
}

所以你会这样称呼它:

        var anotherClass = new SomeOtherClassInSomeOtherDLL();

        // ...

        anotherClass.DoSomethingWithData(_dataSet.DataSource as MyClass);