【问题标题】:C# Passing a class type as a parameterC#将类类型作为参数传递
【发布时间】:2012-06-05 19:14:33
【问题描述】:

这适用于 C#? Passing Class type as a parameter

我有一个实现接口的类适配器。我想用 MyFooClass 实例填充数组结构,我想从外部接收 MyFooClass 的名称或引用。我将在我的适配器代码中实例化它们。

例如:

    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);
            }
        }
    }

【问题讨论】:

  • 有一个答案表明使用.ToThisType().ToTheOtherType() 具有相同的类来控制它会得到什么......,因为在某些时候你正在使用的类知道她应该到达那里.它也很有用。可惜我不能投票,因为它被删除了。但是现在你知道解决方案也存在。谢谢,无名英雄

标签: c# oop interface


【解决方案1】:

Genericstheir constraints 应该做你想做的事,我相信:

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);
        }
    }
}

【讨论】:

  • 如果有超过 1 个接口类型的元素要实例化怎么办? public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;我应该怎么申报?
  • 你明白了! public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;(DataSet ds) where TBaz: IElemRequest, new() where TBar: TElemRequest, new() where Qux : IElemRequest, new()
【解决方案2】:

这可能最好通过使用泛型来解决:

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;
   //..
 }

如果您需要能够访问/实例化多种类型,则声明遵循相同的规则(可以从 msdn 轻松收集):

public void FillWsvcStructs<T, U, V>() where T : IElemRequest, new() 
                                       where U : IFoo, new()
                                       where V : IBar, new()
{

    //..
}

【讨论】:

  • 如果有超过 1 个接口类型的元素要实例化怎么办? public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;我该如何申报?
【解决方案3】:

我想你想要generics

像这样声明你的方法:

public void FillWsvcStructs<T>(DataSet ds)
    where T : IElemRequest, new()
{
    //You can then do
    IElemRequest req = new T();

}

new() 约束要求 T 有一个公共的无参数构造函数,IElemRequest 约束确保它实现 IElemRequest

【讨论】:

  • 如果有超过 1 个接口类型的元素要实例化怎么办? public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;我应该怎么申报?
【解决方案4】:

你需要一个generic:

public void FillWsvcStructs<TBaz>(DataSet ds) where TBaz : IElementRequest, new()
{
    // ...
    IElementRequest req = new TBaz();
    // ...
}

泛型约束 ("where...") 强制您传入的类型实现 IElementRequest 接口并且它具有无参数构造函数。

假设您有一个类似于此的课程Baz

public class Baz : IElementRequest
{
    public Baz()
    {
    }
}

你可以像这样调用这个方法:

DataSet ds = new DataSet();
FillWsvcStructs<Baz>(ds);

附录

多个不同的泛型类型参数可以各自有自己的类型约束:

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();
    // ...
}

【讨论】:

  • 如果有超过 1 个接口类型的元素要实例化怎么办? public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;我该如何申报?
  • 您可以添加与类型参数一样多的类型约束。查看我的编辑。
【解决方案5】:

您可能想使用Activator.CreateInstance

IElemRequest req = (IElemRequest) Activator.CreateInstance(Baz);

如果Baz 表示的类型有一个带参数的构造函数,那么它的复杂性将会增加(因为您必须使用反射或动态调用才能使其工作)。如果Baz 不代表继承自IElemRequest 的类型,您将得到一个丑陋的运行时错误。

【讨论】:

    【解决方案6】:

    方法:

    public void FillWsvcStructs<T>(DataSet ds) where T : IElemRequest, new() {
        ...
        IElemRequest req = new T();
        ...
    }
    

    调用方法:

    FillWsvcStructs<Bez>(ds);
    

    【讨论】:

    • 如果有超过 1 个接口类型的元素要实例化怎么办? public void FillWsvcStructs&lt;TBaz, TBar, TQux&gt;我该如何申报?
    • FillWsvcStructs(DataSet ds) where T : IElemRequest, new() where U : IElemRequest, new() where V : IElemRequest, new() {}
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 2015-04-12
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多