简体   繁体   English

返回泛型方法中的特定类型

[英]Return specific type in generic method

I have written the following method: 我写了以下方法:

public T CreatePackage<T>() where T : new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return compInfoPackage;
        }

        throw new System.NotImplementedException();
}

I check what type T is and according to this I treat my variable Package . 我检查T是什么类型,根据这个我对待我的变量 When I want to return it I get an compiler error. 当我想要返回它时,我得到编译器错误。

"The type ComponentInformationPackage cannot be implicitly converted to T" ComponentInformationPackage类型不能隐式转换为T”

How can I solve this problem? 我怎么解决这个问题?

First: Where a cast doesn't work, a safe cast does work: 第一:如果演员不起作用,安全演员阵容确实有效:

return CompInfoPackage as T;

...provided there's a class constraint on T : ...如果T上有一个class约束:

public static T CreatePackage<T>() where T : class, new() { ... }

Second: Given this code: 第二:鉴于此代码:

var package = new T();
if (typeof(ComponentInformationPackage) == typeof(T))
{
    var compInfoPackage = package as ComponentInformationPackage;

    // ...

    return (T)compInfoPackage; 
}

...you already have the reference package to the new object. ...你已经拥有了新对象的参考package Since it's of type T , the compiler already likes it as a return type. 由于它是T类型,编译器已经将它视为返回类型。 Why not return that? 为什么不回归呢?

var package = new T();
if (typeof(ComponentInformationPackage) == typeof(T))
{
    var compInfoPackage = package as ComponentInformationPackage;

    // ...

    return package; // Same object as compInfoPackage
}

You have to cast to T as your method returns an instance of T not ComponentInformationPackage . 您必须转换为T因为您的方法返回T的实例而不是ComponentInformationPackage

return (T)CompInfoPackage;

The compiler has no chance to get to know that T actually IS a ComponentInformationPackage . 编译器没有机会知道T实际上是一个ComponentInformationPackage However as you already checked it before this cast may never fail. 但是,由于您已经在此演员表之前检查了它,因

However I´m not sure why you have a generic type at all, as only instances of ComponentInformationPackage are handled by your method. 但是我不确定为什么你有一个泛型类型,因为只有ComponentInformationPackage实例由你的方法处理。 Ommit the type-param and the constraint and simply return what you already do. 省略类型参数和约束,并简单地返回您已经执行的操作。

EDIT: I mentioned it already within the comments, you can also return package (without any cast) as the compiler already knows that package is an instance of T . 编辑:我已经在评论中提到它,你也可以返回package (没有任何演员),因为编译器已经知道packageT一个实例。 Last opportunity you have is return (T)(object) CompInfoPackage which however seems quite odd to me. 你有的最后一个机会是return (T)(object) CompInfoPackage ,但这对我来说似乎很奇怪。

Casting back to T will not work as suggested by HimBromBeere and thus is not your solution. 回归到T将不会像HimBromBeere所建议的那样起作用 ,因此不是你的解决方案。 In order for the compiler to accept the cast you will need an additional type constraint of ComponentInformationPackage . 为了让编译器接受转换,您需要一个ComponentInformationPackage的附加类型约束。 So this will be your fix: 所以这将是你的修复:

public T CreatePackage<T>()
    where T : ComponentInformationPackage, new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return (T)compInfoPackage;
        }

        throw new System.NotImplementedException();
}

Also I suggest using the capitalization conventions as a guideline by MSDN. 另外,我建议使用大写约定作为MSDN的指南。 This is irrelevant to your question, but it's a tip. 这与你的问题无关,但这是一个提示。

If you want to handle the object creation based on the type you shouldn't use generics here (as it is NOT generic). 如果你想根据类型处理对象创建,你不应该在这里使用泛型(因为它不是通用的)。 Maybe use a factory pattern to achieve that. 也许使用工厂模式来实现这一目标。

I think what you are trying to achieve is not possible with generics unless you have all your types implement common interface or is of some common abstract type 我认为除非你的所有类型都实现了通用接口或者是一些常见的抽象类型,否则你想要实现的内容是不可能的泛型

public T CreatePackage<T>()
    where T : IPackage, new()
{
        var package = new T();

        if (typeof(ComponentInformationPackage) == typeof(T))
        {
            var compInfoPackage = package as ComponentInformationPackage;

            // ...

            return (T)compInfoPackage;
        }

        throw new System.NotImplementedException();
}

In Above example, all your classes should implement IPackage interface 在上面的示例中,所有类都应该实现IPackage接口

It seems like you want to create instance based on the type passed...you need something like factory pattern. 看起来你想根据传递的类型创建实例......你需要像工厂模式这样的东西。 I think you should reconsider your design 我想你应该重新考虑你的设计

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

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