C#重写抽象类';函数与另一个带“的函数”;“类别类型”;返回类型

C#重写抽象类';函数与另一个带“的函数”;“类别类型”;返回类型,c#,class,types,virtual,abstract,C#,Class,Types,Virtual,Abstract,我试图创建一个基于抽象类的类,并用另一个返回类型为“T”的函数覆盖基类中包含的函数,该返回类型是该类传递的类型 e、 g: 公共抽象类DayInfo { 公共虚拟void GetInfo() { 抛出新的NotImplementedException(); } } 公共类DayInfo:DayInfo { 私人信息; 公共日信息(T数据) { 信息=数据; } public T GetInfo()//这是实现目标的方法: public abstract class DayInfoA<T&g

我试图创建一个基于抽象类的类,并用另一个返回类型为“T”的函数覆盖基类中包含的函数,该返回类型是该类传递的类型

e、 g:

公共抽象类DayInfo
{
公共虚拟void GetInfo()
{
抛出新的NotImplementedException();
}
}
公共类DayInfo:DayInfo
{
私人信息;
公共日信息(T数据)
{
信息=数据;
}

public T GetInfo()//这是实现目标的方法:

public abstract class DayInfoA<T>
{
    public virtual T GetInfo()
    {
        .......
    }
}

public class DayInfoB<T> : DayInfoA<T>
{
    private T info;
    public DayInfoB(T data)
    {
        info = data;
    }

    public override T GetInfo() // << This
    {
      .........
    }
}
公共抽象类DayInfoA
{
公共虚拟T GetInfo()
{
.......
}
}
公共课DayInfoB:DayInfoA
{
私人信息;
公共日信息B(T数据)
{
信息=数据;
}

public override T GetInfo()//否,看起来不像您想要它(假设您不想或不能更改基类声明)。为了使函数解析为多态调用,您需要具有相同的签名和返回类型。否则,它不会以多态方式解析函数,它将只调用函数的基类版本,因为它看到您正在调用该函数(并且您为实例分配的变量属于基类类型)

你可以这样做,但这很难看:

        DayInfo info = new DayInfo<String>("Blah");
        String stuff = ((DayInfo<string>)info).GetInfo();
DayInfo=newdayinfo(“废话”);
字符串stuff=((DayInfo)info.GetInfo();

否,因为函数不会与不同的函数签名匹配

您可以这样定义它:

public abstract class DayInfo
{
    public virtual object GetInfo()
    {
        throw new NotImplementedException();
    }
}
在派生类中,如下所示:

        DayInfoB<int> info = new DayInfoB<int>(25);
        int stuff = info.GetInfo();
public object GetInfo() // << This
{
    return info;
}
这可以通过以下方式实现:

公共抽象类DayInfo
{
受保护的虚拟void GetInfoCore(){
抛出新的NotImplementedException();
}
//或
//受保护的抽象void GetInfoCore();
public void GetInfo(){
GetInfoCore();
}
}
公共类DayInfo:DayInfo
{
私人信息;
公共日信息(T数据){
信息=数据;
}

public new T GetInfo(){/您可以创建一个协变接口,而不是基类,或者作为基类的补充:

void Main()
{
    IDayInfo dayInfo = new DayInfo<string>("hi!");
    object info = dayInfo.GetInfo(); //info == "hi!"
}
public interface IDayInfo
{
    object GetInfo();
}
public interface IDayInfo<out T> : IDayInfo
{
    new T GetInfo();
}

public class DayInfo<T> : IDayInfo<T>
{
    private T info;
    public DayInfo(T data)
    {
        info = data;
    }

    public T GetInfo()
    {
        return info;
    }
    object IDayInfo.GetInfo()
    {
        return this.GetInfo();
    }
}
void Main()
{
IDayInfo dayInfo=新的dayInfo(“嗨!”);
object info=dayInfo.GetInfo();//info==“嗨!”
}
公共接口IDAINFO
{
对象GetInfo();
}
公共接口IDayInfo:IDayInfo
{
新的T GetInfo();
}
公共类DayInfo:IDayInfo
{
私人信息;
公共日信息(T数据)
{
信息=数据;
}
公共T GetInfo()
{
退货信息;
}
对象IDayInfo.GetInfo()
{
返回这个.GetInfo();
}
}
(有关协方差/反方差的信息,请参见)

请注意,
object info
(在我的
Main
的第二行中)在本例中是尽可能精确的,无需强制转换。一旦您将
DayInfo
对象存储在
IDayInfo
变量/字段中,就像我所做的那样(以及您希望在字典中所做的那样),从某种意义上说,
string
的强类型被遗忘了,没有强制转换就无法恢复


更新:添加了
IDayInfo
接口。

为什么不将
GetInfo()
声明为
动态的
?
这样,强制转换应该是自动的。唯一的缺点是您丢失了编译器断言,如果存储
GetInfo()
value的变量不能执行强制转换,它将抛出运行时错误

例如:

public abstract class DayInfo {
    public abstract dynamic GetInfo();
}

public class DayInfo<T> : DayInfo {
    private readonly T _info;
    public DayInfo(T info) {
        _info = info;
    }
    public override dynamic GetInfo() {
        return _info;
    }
}
公共抽象类DayInfo{
公共抽象动态GetInfo();
}
公共类DayInfo:DayInfo{
私人只读T_信息;
公共日信息(T信息){
_信息=信息;
}
公共覆盖动态GetInfo(){
返回_信息;
}
}

您还可以声明类似于
GetInfo(ref T result)的内容
,这样您可以从方法调用中省略
T
类型,并让编译器在运行时推断它,唯一的缺点是您应该传递变量以将结果存储为参数,而不是获取方法返回的结果。

我忘了精确说明我没有在基类中使用类传递的类型,因为我想这样做能够将其作为泛型类型使用,而无需定义任何类型。例如:public SortedDictionary Data=new SortedDictionary()@LouisTakePILLz对于这样一个通用的
DayInfo
的返回类型应该是什么?GetInfo的返回类型是T。你在new DayInfoB中声明的,xxx是数据类型。@Giswin哦,它可以是任何类型,它可以包含类、字符串、int…任何东西。你是对的。它可以是任何东西,这是T的强大部分emplateWell,在这种情况下,我试图避免使用强制类型转换。因此这并没有使它变得非常有用。我觉得这是您将获得的最好结果。如果您将它用作基类,编译器无法了解子类的实现。您能在框架中找到按照您要求的方式运行的任何其他类吗?不幸的是,不,我不知道。由于某些原因…它不起作用。定义的变量无法获取预期的数据。例如:new DayInfo(“Blah”)。GetInfo()仍将是一个void函数。理论上它将执行适当的函数调用,但编译器不会因为
GetInfo
有一个返回类型
void
(如果用作基类)?@McAden是的,它需要强制转换才能工作,但我正试图避免这种情况。例如:((DayInfo)info)。GetInfo()@LouisTakePILLz你确定吗?我试过我的代码,效果很好:不需要铸件,你可以使用DayInfo类型的变量。@ViacheslavIvanov啊,我看到你使用了“var item=new DayInfo(“aaa”)而不是“DayInfo item=new DayInfo(“aaa”)”。这就是为什么我不能让它工作。那么,它似乎工作得很好,只是我必须做一些更改才能让它按我想要的方式工作,请看:难道没有任何方法不必使用已定义的模板变量吗?例如:IDayInfo dayInfo=new dayInfo(“hi!”);只有当您有另一个I
public abstract class DayInfo
{
    public virtual object GetInfo()
    {
        throw new NotImplementedException();
    }
}
public object GetInfo() // << This
{
    return info;
}
DayInfo info = new DayInfo<int>(25);
int stuff = (int)info.GetInfo();
public abstract object GetInfo();
public abstract class DayInfo
{
  protected virtual void GetInfoCore() {
    throw new NotImplementedException();
  }

  // or
  // protected abstract void GetInfoCore();

  public void GetInfo() {
    GetInfoCore();
  }
}

public class DayInfo<T> : DayInfo
{
  private T info;

  public DayInfo(T data) {
    info = data;
  }

  public new T GetInfo() { // << This
    return info;
  }

  protected override void GetInfoCore() {
    GetInfo();
  }
}
void Main()
{
    IDayInfo dayInfo = new DayInfo<string>("hi!");
    object info = dayInfo.GetInfo(); //info == "hi!"
}
public interface IDayInfo
{
    object GetInfo();
}
public interface IDayInfo<out T> : IDayInfo
{
    new T GetInfo();
}

public class DayInfo<T> : IDayInfo<T>
{
    private T info;
    public DayInfo(T data)
    {
        info = data;
    }

    public T GetInfo()
    {
        return info;
    }
    object IDayInfo.GetInfo()
    {
        return this.GetInfo();
    }
}
public abstract class DayInfo {
    public abstract dynamic GetInfo();
}

public class DayInfo<T> : DayInfo {
    private readonly T _info;
    public DayInfo(T info) {
        _info = info;
    }
    public override dynamic GetInfo() {
        return _info;
    }
}