[英]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.