Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.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# 4.0 无法将具体实现强制转换为实现的受约束类型接口_C# 4.0_Design Patterns_Generics_Casting_Type Constraints - Fatal编程技术网

C# 4.0 无法将具体实现强制转换为实现的受约束类型接口

C# 4.0 无法将具体实现强制转换为实现的受约束类型接口,c#-4.0,design-patterns,generics,casting,type-constraints,C# 4.0,Design Patterns,Generics,Casting,Type Constraints,具有受限界面的复杂访客场景: public enum EDTypes { A1, A2 } public interface IProcing { string doIt(string value); } public interface IFooIni : IProcing { } public interface IFooEnd : IProcing { } public class FooIni_A1 : IFooIni { public string doIt(string value)

具有受限界面的复杂访客场景:

public enum EDTypes { A1, A2 }
public interface IProcing { string doIt(string value); }
public interface IFooIni : IProcing { }
public interface IFooEnd : IProcing { }
public class FooIni_A1 : IFooIni { public string doIt(string value) { return "itsIni_A01"; } }
public class FooEnd_A1 : IFooEnd { public string doIt(string value) { return "itsEnd_A01"; } }
public class FooIni_A2 : IFooIni { public string doIt(string value) { return "itsIni_A02"; } }
public class FooEnd_A2 : IFooEnd { public string doIt(string value) { return "itsEnd_A02"; } }
public interface IFooSet<H, T> : IProcing
    where H : IFooIni
    where T : IFooEnd
{
    H FooIni { get; set; }
    List<IProcing> FooBar { get; set; }
    T FooEnd { get; set; }
}
public enum EDTypes{A1,A2}
公共接口IProcing{string doIt(string value);}
公共接口IFooIni:IProcing{}
公共接口IFooEnd:IProcing{}
公共类FooIni_A1:IFooIni{publicstringdoit(stringvalue){返回“itsIni_A01”}
公共类FooEnd_A1:IFooEnd{public string doIt(string value){返回“itsEnd_A01”}
公共类FooIni_A2:IFooIni{publicstringdoit(stringvalue){返回“itsIni_A02”}
公共类FooEnd_A2:IFooEnd{public string doIt(string value){返回“itsEnd_A02”}
公共接口IFooSet:IProcing
其中H:IFooIni
T:IFooEnd在哪里
{
H FooIni{get;set;}
列表FooBar{get;set;}
T fooned{get;set;}
}
并多次具体实施:

public class FooSet_A1 : IFooSet<FooIni_A1, FooEnd_A1>
{
    public FooIni_A1 FooIni { get; set; }
    public List<IProcing> FooBar { get; set; }
    public FooEnd_A1 FooEnd { get; set; }
    public string doIt(string value) { return "itsIni_FooSetA1"; }
}
public class FooSet_A2 : IFooSet<FooIni_A2, FooEnd_A2>
{
    public FooIni_A2 FooIni { get; set; }
    public List<IProcing> FooBar { get; set; }
    public FooEnd_A2 FooEnd { get; set; }
    public string doIt(string value) { return "itsIni_FooSetA2"; }
}
公共类FooSet\u A1:IFooSet
{
公共FooIni_A1 FooIni{get;set;}
公共列表FooBar{get;set;}
公共FooEnd_A1 FooEnd{get;set;}
公共字符串doIt(字符串值){返回“itsIni_FooSetA1”;}
}
公共类FooSet_A2:IFooSet
{
公共FooIni_A2 FooIni{get;set;}
公共列表FooBar{get;set;}
公共FooEnd_A2 FooEnd{get;set;}
公共字符串doIt(字符串值){返回“itsIni_FooSetA2”;}
}
为什么不能:

public class testfoo
{
    private IFooSet<IFooIni, IFooEnd> getInstance(EDTypes type)
    {
        IFooSet<IFooIni, IFooEnd> res = null;
        switch (type)
        {
            case EDTypes.A1:
                /*
                    Unable to cast object of type 
                    '_protoTest.FooSet_A1' 
                    to type 
                    '_protoTest.IFooSet`2[_protoTest.IFooIni,_protoTest.IFooEnd]'.
                */
                res = (IFooSet<IFooIni, IFooEnd>)new FooSet_A1();
                break;
            case EDTypes.A2:
                res = (IFooSet<IFooIni, IFooEnd>)new FooSet_A2();
                break;
        }
        return res;
    }
    public void testIt()
    {
        // +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
        IFooSet<IFooIni, IFooEnd> A1 = (IFooSet<IFooIni, IFooEnd>)getInstance(EDTypes.A1);
        string x = A1.doIt("ASDFG");
        // +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
    }
}
公共类testfoo
{
私有IFooSet getInstance(EDTypes类型)
{
IFooSet res=null;
开关(类型)
{
案例EDTypes.A1:
/*
无法强制转换类型为的对象
“\u protoTest.FooSet\u A1”
打字
“_protoTest.IFooSet`2[_protoTest.IFooIni,_protoTest.IFooEnd]”。
*/
res=(IFooSet)新FooSet_A1();
打破
案例EDTypes.A2:
res=(IFooSet)新FooSet_A2();
打破
}
返回res;
}
公开无效测试()
{
// +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
IFooSet A1=(IFooSet)getInstance(EDTypes.A1);
字符串x=A1.doIt(“ASDFG”);
// +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
}
}
上面有人告诉我要创建另一个接口,但我需要在我的工厂结果上有问题的接口结构


@艾尔德里奇难题告诉我关于“T上的协方差”,帮了我一把 很多人都知道发生了什么。
我还没有找到解决这个问题的办法,而且在最后期限前变得疯狂
但我的问题是“为什么”会发生,他解释得很好。
把更多的细节。标记作为答案

谢谢 上一次出现@Eldritch难题后,我使用了动态关键字解决了我的问题。
我失去了所有的智能感知,但它现在工作了!!! 谢谢@Eldritch难题
代码如下:

*public enum EDTypes { A1, A2 }
public interface IProcing { string doIt(string value); }
public interface IFooIni : IProcing { }
public interface IFooEnd : IProcing { }
public class FooIni_A1 : IFooIni { public string doIt(string value) { return "itsIni_A01"; } }
public class FooEnd_A1 : IFooEnd { public string doIt(string value) { return "itsEnd_A01"; } }
public class FooIni_A2 : IFooIni { public string doIt(string value) { return "itsIni_A02"; } }
public class FooEnd_A2 : IFooEnd { public string doIt(string value) { return "itsEnd_A02"; } }
public interface IFooSet<H, T> : IProcing
    where H : IFooIni
    where T : IFooEnd
{
    H FooIni { get; set; }
    List<IProcing> FooBar { get; set; }
    T FooEnd { get; set; }
}
public class FooSet_A1 : IFooSet<FooIni_A1, FooEnd_A1>
{
    public FooIni_A1 FooIni { get; set; }
    public List<IProcing> FooBar { get; set; }
    public FooEnd_A1 FooEnd { get; set; }
    public string doIt(string value) { return "itsIni_FooSetA1"; }
}
public class FooSet_A2 : IFooSet<FooIni_A2, FooEnd_A2>
{
    public FooIni_A2 FooIni { get; set; }
    public List<IProcing> FooBar { get; set; }
    public FooEnd_A2 FooEnd { get; set; }
    public string doIt(string value) { return "itsIni_FooSetA2"; }
}
public class testfoo
{
    private IProcing getInstance(EDTypes type)
    {
        dynamic res = null;
        switch (type)
        {
            case EDTypes.A1:
                res = new FooSet_A1();
                break;
            case EDTypes.A2:
                res = new FooSet_A2();
                break;
        }
        return res;
    }
    public void testIt()
    {
        // +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
        dynamic A1 = getInstance(EDTypes.A1);
        string s1 = A1.doIt("ASDFG");
        dynamic A2 = getInstance(EDTypes.A2);
        string s2 = A2.doIt("ASDFG");
        // +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
    }
}*
*公共枚举类型{A1,A2}
公共接口IProcing{string doIt(string value);}
公共接口IFooIni:IProcing{}
公共接口IFooEnd:IProcing{}
公共类FooIni_A1:IFooIni{publicstringdoit(stringvalue){返回“itsIni_A01”}
公共类FooEnd_A1:IFooEnd{public string doIt(string value){返回“itsEnd_A01”}
公共类FooIni_A2:IFooIni{publicstringdoit(stringvalue){返回“itsIni_A02”}
公共类FooEnd_A2:IFooEnd{public string doIt(string value){返回“itsEnd_A02”}
公共接口IFooSet:IProcing
其中H:IFooIni
T:IFooEnd在哪里
{
H FooIni{get;set;}
列表FooBar{get;set;}
T fooned{get;set;}
}
公共类FooSet_A1:IFooSet
{
公共FooIni_A1 FooIni{get;set;}
公共列表FooBar{get;set;}
公共FooEnd_A1 FooEnd{get;set;}
公共字符串doIt(字符串值){返回“itsIni_FooSetA1”;}
}
公共类FooSet_A2:IFooSet
{
公共FooIni_A2 FooIni{get;set;}
公共列表FooBar{get;set;}
公共FooEnd_A2 FooEnd{get;set;}
公共字符串doIt(字符串值){返回“itsIni_FooSetA2”;}
}
公共类testfoo
{
私有IProcing getInstance(EDTypes类型)
{
动态res=null;
开关(类型)
{
案例EDTypes.A1:
res=新食物集_A1();
打破
案例EDTypes.A2:
res=新食物集_A2();
打破
}
返回res;
}
公开无效测试()
{
// +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
动态A1=getInstance(EDTypes.A1);
字符串s1=A1.doIt(“ASDFG”);
动态A2=getInstance(EDTypes.A2);
字符串s2=A2.doIt(“ASDFG”);
// +*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
}
}*

因此,您希望将
IConstrained
转换为
IConstrained
,因为
CtrA1
实现了
IClassA
(其他类似)

这有点像将
IEnumerable
转换为
IEnumerable

.Net允许它,因为
IEnumerable
实际上被声明为
IEnumerable
。这被称为T上的协方差

但是,如果您的
IConstrained
具有采用
IClassA
的方法,则这对您不起作用,因为这样做不安全。你知道为什么吗

IEnumerable
转换为
IEnumerable
是安全的,因为只能从
IEnumerable
读取字符串/对象。
但是对于
列表
,它不起作用,因为将
列表
转换为
列表
将使您能够将对象添加到列表(字符串!)。

非常感谢您的帮助。现在有更多的细节,我尝试了“out”关键字,但它不适合我的情况,我需要使用里面的类型。我可能错了,不能