![](/img/trans.png)
[英]The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method
[英]Using Struct as Generic Parameter and casting to the base interface cause the error: must be a non-nullable value type
我需要创建一个 ConcreteProviderX 实例的集合来在它上面执行 LINQ 操作符。 我更喜欢将 struct 用于 ConcreteArgumentsX 类型,但在创建数组时强制转换为基接口 IArguments 会导致编译时错误:类型“IArguments”必须是不可为空的值类型,以便将其用作参数“T”泛型类型或方法“ICommandProvider”(代码 = CS0453)。 对于 ConcreteArgumentsX 类型,我有一个使用类而不是结构的替代实现,但它会导致运行时 System.InvalidCastException(无法将“SetProvider”转换为“ICommandProvider”)。 对于 struct 的情况和 class 的情况,错误将如何解决?
namespace ErrorUsingStructForConcreteArgumentsX
{
interface ICommandProvider<T> where T : struct, IArguments
{
void F(string command, out T? arguments);
}
class ConcreteProvider1 : ICommandProvider<ConcreteArguments1>
{
public void F(string command, out ConcreteArguments1? arguments) { arguments = null; /* other code */ }
}
class ConcreteProvider2 : ICommandProvider<ConcreteArguments2>
{
public void F(string command, out ConcreteArguments2? arguments) { arguments = null; /* other code */ }
}
interface IArguments { }
struct ConcreteArguments1 : IArguments { /* some value type properties */ }
struct ConcreteArguments2 : IArguments { /* some value type properties */ }
class Program
{
static void Main(string[] args)
{
ICommandProvider<ConcreteArguments1> provider = new ConcreteProvider1(); // ok
// compile-time error
var providers = new ICommandProvider<IArguments>[]
{
(ICommandProvider<IArguments>)new ConcreteProvider1(),
(ICommandProvider<IArguments>)new ConcreteProvider2()
};
}
}
}
namespace AlternativeUsingClassForConcreteArgumentsX
{
interface ICommandProvider<IArguments>
{
void F(string command, out IArguments arguments);
}
class ConcreteProvider1 : ICommandProvider<ConcreteArguments1>
{
public void F(string command, out ConcreteArguments1 arguments) { arguments = null; /* other code */ }
}
class ConcreteProvider2 : ICommandProvider<ConcreteArguments2>
{
public void F(string command, out ConcreteArguments2 arguments) { arguments = null; /* other code */ }
}
interface IArguments { }
class ConcreteArguments1 : IArguments { /* some value type properties */ }
class ConcreteArguments2 : IArguments { /* some value type properties */ }
class Program
{
static void Main(string[] args)
{
ICommandProvider<ConcreteArguments1> provider = new ConcreteProvider1(); // ok
// runtime error
var providers = new ICommandProvider<IArguments>[]
{
(ICommandProvider<IArguments>)new ConcreteProvider1(),
(ICommandProvider<IArguments>)new ConcreteProvider2()
};
}
}
}
struct
是值类型,而IArguments
是引用类型。 引用类型是NULLable
,但是值类型不是NULLable
。 由于通用约束总是“AND”,这意味着您的T
应该满足您的where
语句中写入的所有条件 - where T : struct, IArguments
。 所以这就是你出错的原因:
类型“IArguments”必须是不可为空的值类型,以便将其用作泛型类型或方法“ICommandProvider”中的参数“T”
更新:
也许这个实现会很有用:
static void Main(string[] args)
{
ICommandProvider<IArguments> provider = new ConcreteProvider1();
var providers = new ICommandProvider<IArguments>[]
{
new ConcreteProvider1(),
new ConcreteProvider2()
};
}
其他代码如下所示:
interface ICommandProvider<T> where T : IArguments
{
void F(string command, T arguments);
}
class ConcreteProvider1 : ICommandProvider<IArguments>
{
public void F(string command, IArguments arguments)
{
throw new NotImplementedException();
}
}
class ConcreteProvider2 : ICommandProvider<IArguments>
{
public void F(string command, IArguments arguments)
{
throw new NotImplementedException();
}
}
interface IArguments { }
class ConcreteArguments1 : IArguments { /* some value type properties */ }
class ConcreteArguments2 : IArguments { /* some value type properties */ }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.