简体   繁体   English

泛型方法类型转换

[英]Generic method type conversion

I have something like this:我有这样的事情:

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>{
      ...
   }
}

The method FindParameterValue is where I have a problem. FindParameterValue 方法是我遇到问题的地方。 It gets the first parameter of a specific type out of the list and returns its value.它从列表中获取特定类型的第一个参数并返回其值。 Now I get this error: 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>'. 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>'. . . I would like to just supply a derived class which implements Parameter< IArgument>.我只想提供一个派生的 class,它实现了 Parameter<IArgument>。 I can avoid it by doing this:我可以通过这样做来避免它:

public decimal FindParameterValue<T,U>() where T : Parameter<U> where U : class, IArgument

Which causes me to call it like:这使我将其称为:

FindParameterValue<ParameterA, ArgumentA>();

But I'd like to call it with just the 'ParameterA'-type.但我想只用“ParameterA”类型来调用它。

Sorry if this is already solved somewhere.抱歉,如果这已经在某个地方解决了。

Thanks in advance!提前致谢!

The constraint uses the actual types.约束使用实际类型。 If the rules worked as you describe it might very well be possible to write:如果规则如您所描述的那样有效,则很有可能编写:

void MyMethod<T>(T myParameter) where T : List<IFruit>{
    myParameter.Add( new Banana() );
}
....
MyMethod(new List<Apple>());

And you would end up with a list of apples that contains a banana.你最终会得到一个包含香蕉的苹果列表。 You can avoid this by changing the abstract Parameter class to a covariant interface, ie您可以通过将抽象参数 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>();
    }
}

The problem is that every definition of Parameter<T> is a different type.问题是Parameter<T>的每个定义都是不同的类型。 If you remove the generics from the abstract class you will solve your problem.如果您从抽象 class 中删除 generics,您将解决您的问题。 Is there a reason Parameter needs to be generic?是否有理由Parameter需要是通用的? Can you work with pattern matching instead?你可以改用模式匹配吗?

Although the intention isn't clear exactly, try the code below:虽然意图并不明确,但请尝试以下代码:

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.

相关问题 通用方法中的通用类型转换 - Generic type conversion in generic method 类型转换与通用扩展方法不匹配 - Type conversion mismatch with generic extension method 通用继承和类型转换 - Generic inheritance and type conversion 转换为泛型 - Conversion to generic type 类型&#39;&#39;不能用作通用类型或方法&#39;&#39;中的类型参数&#39;&#39;。 没有从“到”的隐式引用转换 - The type '' cannot be used as type parameter '' in the generic type or method ''. There is no implicit reference conversion from '' to '' 该类型不能用作泛型类型或方法中的类型参数“TTo”。 没有隐式引用转换 - The type cannot be used as type parameter 'TTo' in the generic type or method. There is no implicit reference conversion 类型 &#39;&#39; 不能用作泛型类型或方法 &#39;&#39; 中的类型参数 &#39;T&#39;。 没有从 &#39;&#39; 到 &#39;&#39; 的隐式引用转换 - The type '' cannot be used as type parameter 'T' in the generic type or method ''. There is no implicit reference conversion from '' to '' 该类型不能在泛型类型或方法中用作类型“T”。 没有隐式的引用转换 - The type cannot be used as type 'T' in the generic type or method. There is no implicit reference conversion from to 通用接口类型转换问题 - Generic Interface type conversion issues C# 中的泛型类型转换 - generic type conversion in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM