簡體   English   中英

C#方法泛型返回類型轉換

[英]C# method generic return type casting

我試圖在具有泛型返回類型的接口中創建一個方法,但我無法將泛型強制轉換為特定的類型/類。 但是,如果我將泛型放在接口上而不是方法上,我可以進行轉換。

換句話說,為什么這樣做

public class Rain {
    public string propA {get;set;}
}
public interface IFoo<T> {
    T foo();
}

public class Bar : IFoo<Rain> {
    Rain foo() { 
        //...
        return new Rain();
    }
}

public bar = new Bar();
Rain rain = bar.foo();

但是不可能這樣做嗎?

public class Rain {
    public string propA {get;set;}
}
public interface IFoo {
    T foo<T>();
}

public class Bar : IFoo {
    T foo<T>() { 
        //...
        return new Rain();
    }
}

public bar = new Bar();
Rain rain = bar.foo<Rain>();

有沒有其他方法(不使用Convert.ChangeType() )?

第二個代碼片段無法編譯,因為Rain不是T

在類中提供type參數時,沒有問題,因為該方法只能返回類聲明中已提供的類型。 換句話說 - T foo()成為Rain foo

但是,當類型參數提供給方法時,該方法必須返回提供給它的任何類型 - 因此您不能返回除T之外的任何類型。 換句話說,編譯器不能強制調用方法只使用foo<Rain>() ,但它可以強制foo方法返回T

不同之處是:

// On this line you specify that the interface's generic type paramter 'T' is of type 'Rain',
// so the method implements the interface and returns a 'Rain'
public class Bar : IFoo<Rain> {
    Rain foo() { // <= implements IFoo<Rain>.foo, where T = Rain so foo returns 'Rain'
        return new Rain();

// In this version, the generic type parameter is declared on the method. It could be any type when the method is called, yet you always return a 'Rain'
public class Bar : IFoo {
    T foo<T>() { // <= implements IFoo.foo<T> but the type of T is not specified yet
        return new Rain();

這個“解決方案”取決於你的意圖。

  • 你為什么不想接口的泛型參數?
  • 另外,如果你總是返回Rain ,你為什么要在foo方法上使用泛型參數呢?

當然,無論如何,你可以像這樣投出它:

T Foo<T>()
{
    object result;
    result = new Rain();
    return (T)result; // note, this will throw at runtime if 'result' cannot be cast to 'T'
}

// call like this:
Bar.Foo<Rain>();

但我認為你的第一種方法IFoo<T>非常有意義,為什么不使用呢?

UPDATE

根據您的評論:您還可以定義多個通用參數:

public interface IFoo<T1, T2>
{
    T1 foo();
    T2 foo2();
}

// implementation:
public class Bar : IFoo<Rain, Other>
{
    Rain foo() { /* ... */ }
    Other foo2() { /* ... */ }
}

如果你需要你的接口支持任意一組類,並且調用者確定使用哪些類,那么像這樣的東西是最通用的解決方案。

public class Bar : IFoo {
    T foo<T>() { 
        if (typeof(T)==typeof(Rain))
           return new Rain() as T;
        if (typeof(T)==typeof(Snow))
           return new Snow() as T;
        Throw new ArgumentException("Not implemented for " + typeof(T).Name);
    }
}

如果你所有的T都有一個共同的界面,那么你可以做的就是你感興趣的;

public class Snow : IWeather {...}
public class Rain: IWeather {...}
public class Bar : IFoo {
    IWeather  foo<T>() T : IWeather { 
        if (typeof(T)==typeof(Rain))
           return new Rain();
        if (typeof(T)==typeof(Snow))
           return new Snow();
        Throw new ArgumentException("Not implemented for " + typeof(T).Name);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM