[英]Generic method type conversion
我有這樣的事情:
interface IArgument{ ... }
class ArgumentA : IArgument{ ... }
abstract class Parameter<T> where T : class, IArgument{
...
abstract decimal GetValue(T args);
...
}
class ParameterA : Parameter<ArgumentA>{
override decimal GetValue(ArgumentA args){
...
}
}
abstract class Calculation{
List<Parameter<IArgument>> Parameters{get;set;}
decimal FindParameterValue<T>() where T : Parameter<IArgument>{
...
}
}
FindParameterValue 方法是我遇到問題的地方。 它從列表中獲取特定類型的第一個參數並返回其值。 現在我收到此錯誤: Error CS0311 The type 'ParameterA' cannot be used as type parameter 'T' in the generic type or method 'Calculation.FindParameterValue<T>()'. There is no implicit reference conversion from 'ParameterA' to 'Parameter<IArgument>'.
Error CS0311 The type 'ParameterA' cannot be used as type parameter 'T' in the generic type or method 'Calculation.FindParameterValue<T>()'. There is no implicit reference conversion from 'ParameterA' to 'Parameter<IArgument>'.
. 我只想提供一個派生的 class,它實現了 Parameter<IArgument>。 我可以通過這樣做來避免它:
public decimal FindParameterValue<T,U>() where T : Parameter<U> where U : class, IArgument
這使我將其稱為:
FindParameterValue<ParameterA, ArgumentA>();
但我想只用“ParameterA”類型來調用它。
抱歉,如果這已經在某個地方解決了。
提前致謝!
約束使用實際類型。 如果規則如您所描述的那樣有效,則很有可能編寫:
void MyMethod<T>(T myParameter) where T : List<IFruit>{
myParameter.Add( new Banana() );
}
....
MyMethod(new List<Apple>());
你最終會得到一個包含香蕉的蘋果列表。 您可以通過將抽象參數 class 更改為協變接口來避免這種情況,即
interface IArgument { }
class ArgumentA : IArgument {}
interface IParameter<out T> where T :IArgument{ }
class ParameterA : IParameter<ArgumentA>{}
class Calculation
{
void FindParameterValue<T>() where T : IParameter<IArgument>
{ }
void Test()
{
FindParameterValue<ParameterA>();
}
}
問題是Parameter<T>
的每個定義都是不同的類型。 如果您從抽象 class 中刪除 generics,您將解決您的問題。 是否有理由Parameter
需要是通用的? 你可以改用模式匹配嗎?
雖然意圖並不明確,但請嘗試以下代碼:
public interface IArgument { }
public class ArgumentA : IArgument
{
public decimal Value { get; }
}
public abstract class Parameter
{
public abstract decimal GetValue(IArgument args);
}
public class ParameterA : Parameter
{
public override decimal GetValue(IArgument args)
{
if (args is ArgumentA argA)
{
return argA.Value;
}
return 0m;
}
}
public abstract class Calculation
{
List<Parameter> Parameters { get; } = new List<Parameter>();
public decimal FindParameterValue<T>(IArgument argument) where T : Parameter
{
var item = Parameters.OfType<T>().FirstOrDefault();
if (item != null)
{
return item.GetValue(argument);
}
return 0m;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.