【问题标题】:Is it possible create a new instance of a generic type inside the body of a generic method?是否可以在泛型方法的主体内创建泛型类型的新实例?
【发布时间】:2014-09-05 18:02:38
【问题描述】:

假设以下方法,我知道它不起作用:

我想创建一个泛型类型的新实例

public List<TPer> getDATA<TPer>(TPer per, int acao) where TDal: new()
{
    //Is it possible create a new instance of a generic type inside the body of a generic method?
    TDal dal = new TDal(); //<-- I know it is NOT OK 
    List<TPer> lst = new List<TPer>();

    lst = dal.getDATA(per, acao);
    return lst;
}

我可以这样写:

List<TPer> getDATA<TPer,TDal>(TPer per, int acao) where TDal: new()

但是,将调用此方法的程序无权访问TDal

是否可以使用空参数调用此方法?还是在泛型方法体内创建一个泛型类型的新实例?

&lt;TDal&gt; 也将是泛型的,但我不知道是否可以在 C# 中的这个泛型方法中创建它作为新的泛型类型。

【问题讨论】:

  • 我不知道您想要达到什么目的 - 或者您为什么要创建一个新的 List&lt;TPer&gt; 然后立即丢弃它。 TDal dal = new TDal()“不行”是怎么回事?
  • 该方法的第一个版本没有显示TDal 应该是什么以及它来自哪里。怎么样?
  • 如果你编辑你的previous question而不是重新发布会更好。
  • @JonSkeet,由于编译器错误,这不正常:“找不到类型或命名空间名称 'TDal'”。而 lst 是方法的返回。
  • @Jon,谢谢你的评论,我想做一个TDal的新实例,TDal也是通用的,但我不知道是否可以在这个通用方法中创建它在 C# 中。

标签: c# generics optimization parameters instance


【解决方案1】:

你可以让你的泛型类型实现一个接口。然后在您的泛型方法中设置限制以仅接受实现该接口的类型。这将允许您在新构建的项目上调用方法,因为它已知具有这些方法。

public interface ITest
{
    void DoSomething();
}

public void GetData<T, U>(T varA, int acao) where U: ITest, new()
{
    var item = new U();
    item.DoSomething();
} 

【讨论】:

  • 非常感谢。我喜欢这个答案。好吧,我在 C# 和泛型方面的知识并不先进,而且我的实际项目比这个问题中的代码复杂得多,但我会尝试实施你的建议。
  • 如果该方案可行,请将其标记为正确答案。
  • 这不是我想要的,但它帮助我更好地理解了泛型。如果可能的话,想再等一下,以获得更多答案。也许如果我标记为正确答案,人们就不会再给出答案了。
【解决方案2】:

通用 getDATA 如何知道什么是 TDal? 它必须在方法 getDATA 或包含该方法的类中声明,即

class MyGenericClass<TDal> where TDal:new()
{
    public List<TPer> getDATA<TPer>(TPer per, int acao) where TDal : new()
    {
        TDal dal = new TDal();
        List<TPer> lst = new List<TPer>();

        lst = dal.getDATA(per, acao);
        return lst;
    }
}

在这两种情况下,调用者都需要知道 TDal。

如果您需要避免这种情况,您可以在 getDATA 中进行一些操作,从 per.GetType() 检索 TDal 类型,然后实例化该类。 即

    public List<TPer> getDATA<TPer>(TPer per, int acao)
    {

        List<TPer> lst = new List<TPer>();

        IDal dal;

        switch (per.GetType().Name)
        {
            case "Person": 
                dal = new DalPerson();
                break;
            case "Car":
                dal = new DalCar();
                break;
            default:
                throw new InvalidOperationException("I dont like per");
        }

        lst = dal.getDATA(per, acao);
        return lst;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    相关资源
    最近更新 更多