简体   繁体   English

是否有一个通用类不需要new(),而单个方法需要new()?

[英]Is it possible to have a Generic class not requiring new() with single method requiring new()?

Is it possible in C# to have a method of a generic driven class require new, but not require new on the whole class? 在C#中,是否有一个通用驱动类的方法在整个类上需要new而不是new?

public class Response<T> //not where T:new() 
{      
    public void AddTotal<T>() where T : new()
    {
         var totaledObject = new T();
        // do all the useful stuff I need with the new generic
    }

}

I use this response for many different scenarios, the T does not always have a new(), and for those scenarios I will not use the AddTotal function, but for a few I would like to have it. 我在许多不同的情况下使用此响应,T并不总是具有new(),对于这些情况,我将不使用AddTotal函数,但对于某些情况,我希望使用它。 Is this possible? 这可能吗?

Note: I know I can do a different generic variable name and just pass that to the function, but this breaks the indication that it has to be of the same type as T. 注意:我知道我可以做一个不同的泛型变量名并将其传递给函数,但这打破了必须与T具有相同类型的指示。

You can get around this by pushing the problem out to the calling code. 您可以通过将问题推送到调用代码来解决此问题。 Add an argument to either have the calling code provide the object instance you need or have the calling code provide the method you need to create the object: 添加一个参数,以使调用代码提供所需的对象实例,或者使调用代码提供创建对象所需的方法:

public void AddTotal<T>(T totaledObject) 
{
    // do all the useful stuff I need with totaledObject
}

//call it: AddTotal(new Object())

or 要么

public void AddTotal<T>(Func<T> createObject) 
{
     var totaledObject = createObject();
    // do all the useful stuff I need with the new generic
}

The trick with this option is that you can't just pass a constructor to that object. 使用此选项的技巧是,您不能仅将构造函数传递给该对象。 You have to wrap calls in another delegate, which can be done with a quick lambda expression: 您必须将调用包装在另一个委托中,这可以使用快速的lambda表达式完成:

AddTotal(() => new Object());

Is it possible in C# to have a method of a generic driven class require new, but not require new on the whole class? 在C#中,是否有一个通用驱动类的方法在整个类上需要new而不是new?

Only if you specify different type parameter, which you don't want to do. 仅当您指定不同的类型参数时,才不需要这样做。 A generic type parameter constraint exists for any generic type argument you specify. 您指定的任何泛型参数都存在泛型参数约束。 As you want T for the class and method declaration to be the same T , the constraint will exist for both. 由于您希望类和方法声明的T为相同的T ,因此两者都将存在约束。

If you want to specify another generic type parameter, you could do something hacky like this: 如果要指定另一个泛型类型参数,则可以这样做:

public class X<T>
{
    public void Y<OtherT>() where OtherT : T, new()
    {
    }
}

Thus constraining OtherT to be of type T declared in the class or a derivative. 因此,将OtherT约束为在类中声明的T类型或派生类。 There's no guarantee there will be an exact match on the type. 无法保证类型会完全匹配。

You don't have to constrain T to new (). 您不必将T约束为new()。 Just allow it. 只要允许它。 Use 'where T : class, new()' as your class constraint. 使用“ where T:class,new()”作为类约束。 You don't need anything on the method as new T() can now be used. 您不需要任何方法,因为现在可以使用新的T()了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM