Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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# 用where子句重写泛型函数_C#_.net_Generics_Overriding - Fatal编程技术网

C# 用where子句重写泛型函数

C# 用where子句重写泛型函数,c#,.net,generics,overriding,C#,.net,Generics,Overriding,已编辑:重建示例代码以包含更相关的对象集 我有一个有趣的情况,我很难找到解决方案。我有一个抽象类和一个使用泛型的抽象函数(参见下面的示例代码)。在继承类中,我试图重载函数,但是我得到了 错误CS0030:无法将类型“Sample.Thingy”转换为“T”(CS0030) 当然,这不是我真正的代码,但这段代码产生的结果与我得到的结果相同。如果我尝试将返回值强制转换为(T),我会得到类似的错误。如果我尝试添加where T:BaseThingy或where T:Thingy,那么 错误CS0460

已编辑:重建示例代码以包含更相关的对象集

我有一个有趣的情况,我很难找到解决方案。我有一个抽象类和一个使用泛型的抽象函数(参见下面的示例代码)。在继承类中,我试图重载函数,但是我得到了

错误CS0030:无法将类型“Sample.Thingy”转换为“T”(CS0030)

当然,这不是我真正的代码,但这段代码产生的结果与我得到的结果相同。如果我尝试将返回值强制转换为(T),我会得到类似的错误。如果我尝试添加
where T:BaseThingy
where T:Thingy
,那么

错误CS0460:'Sample.Container.GetThingy(Guid)':无法为重写和显式接口实现方法指定约束(CS0460)

名称空间示例{
//thingies的抽象基类
基于公共抽象类的{
私有Guid m_ID;
私有字符串m_Name;
公共基础(){
m_ID=Guid.NewGuid();
}
公共基础(Guid id){
m_ID=ID;
}
公共Guid ID{
得到{
返回m_ID;
}
}
公共字符串名{
得到{
返回m_名称;
}
设置{
m_Name=值;
}
}
}
//容器的抽象基类
公共抽象类BaseContainer{
公共摘要T GetThingy(Guid id),其中T:BaseThingy;
}
//继承自BaseThingy
公共类红色:BaseThingy{
创建私有日期时间m_;
公共RedThingy():基(){
m_Created=DateTime.Now;
}
公共RedThingy(Guid id):基(id){
m_Created=DateTime.Now;
}
已创建公共日期时间{
得到{
返回创建的m_;
}
}
}
//继承自BaseThingy
公共类BlueThingy:BaseThingy{
公共BlueThingy():base(){
}
公共BlueThingy(Guid id):基(id){
}
}
//从BaseContainer继承
公共类容器:BaseContainer{
private System.Collections.Generic.Dictionary m_RedThingies;
private System.Collections.Generic.Dictionary m_BlueThingies;
公共容器(){
m_Thingies=new System.Collections.Generic.Dictionary();
}
公共覆盖T GetThingy(Guid id),其中T:BaseThingy{
if(typeof(T)=typeof(RedThingy){
如果(m_RedThingies.ContainsKey(id)){
返回m_RedThingies[id];
}否则{
返回null;
}
}else if(typeof(T)=typeof(BlueThingy)){
如果(m_BlueThingies.ContainsKey(id)){
返回m_BlueThingies[id];
}否则{
返回null;
}
}否则{
返回null;
}
}
公共无效添加项(红色项){
if(item!=null&&!m_RedThingies.ContainsKey(item.ID)){
m_RedThingies.Add(item.ID,item);
}
}
公共无效添加项(蓝色项){
if(item!=null&&!m_BlueThingies.ContainsKey(item.ID)){
m_BlueThingies.Add(item.ID,item);
}
}
}
}

答案是,您传递的类型必须继承自
BaseThingy
,但这并不意味着您可以向它强制转换
Thingy
。让我举一个例子来简化它:

abstract class BaseThingy
{
}

class Thingy1 : BaseThingy
{
    public void DoSomething()
    {
    }
}

class Thingy2 : BaseThingy
{
    public void DoSomethingElse()
    {
    }
}

class Foo
{
    static T GetItem<T>() where T : BaseThingy
    {
        //Won't compile, Thingy1, while deriving from BaseThingy
        //Could not be the same type of T, derive from it or have
        //An implicit cast operator to T.
        return new Thingy1();
    }

    static void Bar()
    {
        var result = GetItem<Thingy2>();
        //But your method is returning a Thingy1,
        //which doesn't have the following method
        result.DoSomethingElse();
    }
}
基于抽象类的东西
{
}
第1类:基本类
{
公共无效剂量测定法()
{
}
}
类别2:基本类
{
公共无效DoSomethingElse()
{
}
}
福班
{
静态T GetItem(),其中T:BaseThingy
{
//从BaseThingy派生时不会编译,Thingy1
//不能是同一类型的T,从它派生或具有
//对T的隐式强制转换运算符。
返回新内容1();
}
静态空心条()
{
var result=GetItem();
//但你的方法是返回一个东西1,
//哪一个没有下面的方法
结果:DoSomethingElse();
}
}

Bar()
将期望
结果
的类型为
Thingy2
,但是
GetItem
试图返回
Thingy1
问题是,由于您已经在基类中设置了约束,所以不需要在派生类中再次指定它们。这就是为什么它会给出错误的原因

除此之外,它还产生了这个错误,我不明白您有什么问题,只是不在继承的类中指定约束

为了解决转换问题,您必须强制转换它:

public T Get<T>() where T : Thingy
{
    RedThingy thingy = GetRedThingy();
    return (T)thingy;
}
public T Get(),其中T:Thingy
{
RedThingy=GetRedThingy();
返回(T)thingy;
}
如果编译器不允许您这样做(我现在没有打开VisualStudio),您可以先将其强制转换为object,然后再转换为t(这是一种解决方法,可以完成此工作)

public T Get(),其中T:Thingy
{
RedThingy=GetRedThingy();
返回(T)((对象)thingy);
}

希望能有所帮助。

最快的解决方法是将基本实现约束更改为Thingy而不是BaseThingy。如果这对应用程序没有意义,那么很可能您只是没有使用最佳设计模式来解决问题。在后一种情况下,If可以对您的pr进行更多解释那么我相信我们可以给你一些其他的建议来解决这个问题。

在我的原始代码中,我有一个基类,它被其他三个类继承。这三个类中的每一个都是独立的
public T Get<T>() where T : Thingy
{
    RedThingy thingy = GetRedThingy();
    return (T)thingy;
}
public T Get<T>() where T : Thingy
{
    RedThingy thingy = GetRedThingy();
    return (T)((object)thingy);
}