C# 将类类型作为参数传递
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10903452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C# Passing a class type as a parameter
提问by apacay
This for C#? Passing Class type as a parameter
这是针对 C# 的? 传递类类型作为参数
I have a class adapter that implements an Interface. I want to fill an array structure with MyFooClass instances where MyFooClass's name or reference I want to receive it from outside. I'll instantiate them inside my adapter code.
我有一个实现接口的类适配器。我想用 MyFooClass 实例填充数组结构,其中 MyFooClass 的名称或引用我想从外部接收它。我将在我的适配器代码中实例化它们。
For example:
例如:
public void FillWsvcStructs(DataSet ds, ClassType Baz)
{
IFoo.Request = ds.DataTable[0].Request;
IFoo.Modulebq = string.Empty;
IFoo.Clasific = string.Empty;
IFoo.Asignadoa = ds.DataTable[0].Referer;
IFoo.Solicita = "Jean Paul Goitier";
// Go with sub-Elems (Also "Interfaceated")
foreach (DataSet.DataTableRow ar in ds.DataTable[1])
{
if ((int) ar.StatusOT != (int)Props.StatusOT.NotOT)
{
///From HERE!
IElemRequest req = new (Baz)(); // I don't know how to do it here
///To HERE!
req.Id = string.Empty;
req.Type = string.Empty;
req.Num = string.Empty;
req.Message = string.Empty;
req.Trkorr = ar[1];
TRequest.Add(req);
}
}
}
采纳答案by Jesse C. Slicer
Genericsand their constraintsshould do what you want, I believe:
public void FillWsvcStructs<ClassType>(DataSet ds) where ClassType : IElemRequest, new()
{
IFoo.Request = ds.DataTable[0].Request;
IFoo.Modulebq = string.Empty;
IFoo.Clasific = string.Empty;
IFoo.Asignadoa = ds.DataTable[0].Referer;
IFoo.Solicita = "Jean Paul Goitier";
// Go with sub-Elems (Also "Interfaceated")
foreach (DataSet.DataTableRow ar in ds.DataTable[1])
{
if ((int) ar.StatusOT != (int)Props.StatusOT.NotOT)
{
IElemRequest req = new ClassType();
req.Id = string.Empty;
req.Type = string.Empty;
req.Num = string.Empty;
req.Message = string.Empty;
req.Trkorr = ar[1];
TRequest.Add(req);
}
}
}
回答by BrokenGlass
That's probably best solved by using generics:
这可能最好通过使用泛型来解决:
public void FillWsvcStructs<T>(DataSet ds) where T : IElemRequest, new()
{
//..
//new() constraint enables using default constructor
IElemRequest req = new T();
//IElemRequest constraint enables using interface properties
req.Id = string.Empty;
//..
}
If you have multiple types that you need to be able to access/instantiate, the declaration follows the same rules (as may easily be gathered from msdn):
如果您有多种类型需要访问/实例化,则声明遵循相同的规则(很容易从 msdn 中收集到):
public void FillWsvcStructs<T, U, V>() where T : IElemRequest, new()
where U : IFoo, new()
where V : IBar, new()
{
//..
}
回答by FishBasketGordo
You need a generic:
你需要一个通用的:
public void FillWsvcStructs<TBaz>(DataSet ds) where TBaz : IElementRequest, new()
{
// ...
IElementRequest req = new TBaz();
// ...
}
The generic constraint ("where...") enforces that the type you pass in implements the IElementRequestinterface and that it has a parameter-less constructor.
泛型约束 (" where...") 强制您传入的类型实现IElementRequest接口并且它具有无参数构造函数。
Assuming you had a class Bazsimilar to this:
假设你有一个Baz类似的类:
public class Baz : IElementRequest
{
public Baz()
{
}
}
You would invoke this method like so:
你会像这样调用这个方法:
DataSet ds = new DataSet();
FillWsvcStructs<Baz>(ds);
Addendum
附录
Multiple, different, generic type parameters can each have there own type constraint:
多个不同的泛型类型参数每个都可以有自己的类型约束:
public void FillWsvcStructs<TFoo, TBar, TBaz>(DataSet ds)
where TFoo : IFoo, new()
where TBar : IBar, new()
where TBaz : IElementRequest, new()
{
// ...
IFoo foo = new TFoo();
IBar bar = new TBar();
IElementRequest req = new TBaz();
// ...
}
回答by DaveShaw
I think you want generics.
我想你想要泛型。
Declare your method like this:
像这样声明你的方法:
public void FillWsvcStructs<T>(DataSet ds)
where T : IElemRequest, new()
{
//You can then do
IElemRequest req = new T();
}
The new()constraint requires Tto have a public parameterless constructor, and the IElemRequestconstraint ensures it implements IElemRequest.
该new()约束要求T有一个公共的无参数的构造函数,而IElemRequest约束可以确保它实现IElemRequest。
回答by 48klocs
You probably want to use Activator.CreateInstance.
您可能想要使用Activator.CreateInstance。
IElemRequest req = (IElemRequest) Activator.CreateInstance(Baz);
IElemRequest req = (IElemRequest) Activator.CreateInstance(Baz);
If the type that Bazrepresents has a constructor that takes parameters, the complexity of that will grow (as you'll have to use Reflection or dynamic calls to make it work). If Bazdoesn't represent a type that inherits from IElemRequest, you will get an ugly runtime error.
如果Baz表示的类型具有带参数的构造函数,则其复杂性将会增加(因为您必须使用反射或动态调用才能使其工作)。如果Baz不代表从 继承的类型IElemRequest,您将得到一个难看的运行时错误。
回答by Mikael
The method:
方法:
public void FillWsvcStructs<T>(DataSet ds) where T : IElemRequest, new() {
...
IElemRequest req = new T();
...
}
Calling the method:
调用方法:
FillWsvcStructs<Bez>(ds);

