Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法通过ParentA<;ChildA>;泛型方法的实例(IParent<;IChild>;)_C#_Interface - Fatal编程技术网

C# 无法通过ParentA<;ChildA>;泛型方法的实例(IParent<;IChild>;)

C# 无法通过ParentA<;ChildA>;泛型方法的实例(IParent<;IChild>;),c#,interface,C#,Interface,我想概括一下Util.CheckParentA和ParentB类的方法 但是,错误显示:无法从ParentA转换为IParent public interface IChild {} public interface IParent<TChild> where TChild : IChild { public string message { get; set; } List<TChild> list { get; set; } } public cla

我想概括一下
Util.Check
ParentA
ParentB
类的方法
但是,错误显示:无法从ParentA转换为IParent

public interface IChild {}
public interface IParent<TChild> where TChild : IChild
{
    public string message { get; set; }
    List<TChild> list { get; set; }
}

public class ChildA : IChild { }
public class ChildB : IChild { }

public class ParentA : IParent<ChildA>
{
    public string message { get; set; }
    public List<ChildA> list { get; set; }
}

public class ParentB : IParent<ChildB>
{
    public string message { get; set; }
    public List<ChildB> list { get; set; }
}

public static class Util
{
    public static IParent<IChild> Check<IParent>(IParent<IChild> parent)
    {
        parent.message = "test";
        return parent;
    }
}

var parentA = new ParentA();
var parentB = new ParentB();
var resultA = Util.Check<ParentA>(parentA); // got an error here
var resultB = Util.Check<ParentB>(parentB); // got an error here
公共接口IChild{}
公共接口iPart,其中TChild:IChild
{
公共字符串消息{get;set;}
列表{get;set;}
}
公共类ChildA:IChild{}
公共类ChildB:IChild{}
公共类家长A:IParent
{
公共字符串消息{get;set;}
公共列表{get;set;}
}
公共类ParentB:IParent
{
公共字符串消息{get;set;}
公共列表{get;set;}
}
公共静态类Util
{
公共静态iPart检查(iPart父级)
{
parent.message=“测试”;
返回父母;
}
}
var parentA=新parentA();
var parentB=新的parentB();
var resultA=Util.Check(parentA);//这里有个错误
var resultB=Util.Check(parentB);//这里有个错误
错误显示:

Error   CS1503  Argument 1: cannot convert from 'ParentA' to 'IParent<IChild>'
Error   CS1503  Argument 1: cannot convert from 'ParentB' to 'IParent<IChild>'
错误CS1503参数1:无法从“ParentA”转换为“IParent”
错误CS1503参数1:无法从“ParentB”转换为“IParent”

是的,没错-因为
ParentA
不是
iPart
。想想如果允许的话会发生什么。下面的代码可以:

// Invalid code: if the first line were valid, the rest would be unsafe.
IParent<IChild> parent = new ParentA();
List<IChild> list = parent.list;
IChild child = new ChildB();
list.Add(child);
//无效代码:如果第一行是有效的,那么其余的就不安全了。
i父对象=新父对象a();
List=parent.List;
IChild child=new ChildB();
列表。添加(子项);
这只是在一个对象中添加了一个
ChildB
,该对象实际上是一个
列表
,破坏了类型安全性。但是,如果你能将
ParentA
视为
IParent
,那么每一行都是可以的


通用差异允许在某些情况下执行此类操作,但规则确保这样做是安全的。在这种情况下,这样做是不安全的,因此是禁止的。

请参见上面的评论)作为旁白,我强烈建议您遵循.NET命名约定,即使是对于这样的示例代码也是如此。接口成员也无法访问modifier@BasilKosovan:它可以用C#8表示。在这种情况下这样做并不惯用,但是这里显示的类型都是编译的——只有最后两行没有编译。Thx@jon skeet,但是,
IParent parent=new ParentA()获取错误:CS0266无法将类型“ParentA”隐式转换为“IParent”。存在显式转换(您是否缺少演员阵容?@ytk:是的,这就是重点。这不是有效的代码,因为如果第一行是有效的,那么其余的就不安全了。答案的目的是通过一个简单的例子向您解释代码无效的原因。为了澄清这一点,我在代码片段中添加了一条注释。