在C#中,将泛型类型强制转换为其基类的最佳方法是什么?

在C#中,将泛型类型强制转换为其基类的最佳方法是什么?,c#,generics,casting,C#,Generics,Casting,我的目标如下: public class ItemChange<T> where T : MyBase { public DateTime When { get; set; } public string Who { get; set; } public T NewState; public T OldState; } public类ItemChange其中T:MyBase { 当{get;set;}时的公共日期时间 公共字符串Who{get;set;} 公共电视台; 国家公共部门

我的目标如下:

public class ItemChange<T> where T : MyBase
{
public DateTime When { get; set; }
public string Who { get; set; }
public T NewState;
public T OldState;
}
public类ItemChange其中T:MyBase
{
当{get;set;}时的公共日期时间
公共字符串Who{get;set;}
公共电视台;
国家公共部门;
}
我试图将
ItemChange
的实例强制转换为
ItemChange
,但我得到了一个强制转换异常

无法强制转换类型为的对象


什么是将泛型类型强制转换为其基本类型的正确方法(假设上面的where约束)

您不能直接执行此操作,因为C#中的类不支持协变。但是,您可以使用接口执行此操作:

public interface IItemChange<out T> where T : MyBase
{
    DateTime When { get; set; }
    string Who { get; set; }
    T NewState { get; }
    T OldState { get; }
}

public class ItemChange<T> : IItemChange<T> where T : MyBase
{
    public DateTime When { get; set; }
    public string Who { get; set; }
    public T NewState { get; set; }
    public T OldState { get; set; }
}
公共接口IItemChange,其中T:MyBase
{
日期时间当{get;set;}
字符串Who{get;set;}
T NewState{get;}
T旧状态{get;}
}
公共类ItemChange:IItemChange其中T:MyBase
{
当{get;set;}时的公共日期时间
公共字符串Who{get;set;}
公共T新闻状态{get;set;}
公共T旧状态{get;set;}
}
然后你可以做:

IItemChange<MyBase> base = new ItemChange<MySubclass>();
IItemChange base=new ItemChange();

对于
MyBase

的某些子类
MySubclass
,您不能直接执行此操作,因为C中的类不支持协方差。但是,您可以使用接口执行此操作:

public interface IItemChange<out T> where T : MyBase
{
    DateTime When { get; set; }
    string Who { get; set; }
    T NewState { get; }
    T OldState { get; }
}

public class ItemChange<T> : IItemChange<T> where T : MyBase
{
    public DateTime When { get; set; }
    public string Who { get; set; }
    public T NewState { get; set; }
    public T OldState { get; set; }
}
公共接口IItemChange,其中T:MyBase
{
日期时间当{get;set;}
字符串Who{get;set;}
T NewState{get;}
T旧状态{get;}
}
公共类ItemChange:IItemChange其中T:MyBase
{
当{get;set;}时的公共日期时间
公共字符串Who{get;set;}
公共T新闻状态{get;set;}
公共T旧状态{get;set;}
}
然后你可以做:

IItemChange<MyBase> base = new ItemChange<MySubclass>();
IItemChange base=new ItemChange();

对于
MyBase

的某些子类
MySubclass
,您需要定义一个显式强制转换运算符

using System;
using System.Collections.Generic;
using System.Linq;

namespace brosell
{

public class MyBase
{

}



public class ItemChange<T> where T : MyBase
{
    public DateTime When { get; set; }
    public string Who { get; set; }
    public T NewState;
    public T OldState;

    public static explicit operator ItemChange<MyBase>(ItemChange<T> i)
   {
      return new ItemChange<MyBase> { When = i.When, Who = i.Who, NewState = i.NewState, OldState = i.OldState};
   }

}

public class Sub1: MyBase
{

}

public class Sub2: MyBase
{

}

   public class HelloWorld
   {
    public static void Main(string[] args)
    {
        ItemChange<Sub1> item = new ItemChange<Sub1>();


        ItemChange<MyBase> itemCasted = (ItemChange<MyBase>)item;
        }
   } 
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间brosell
{
公共类MyBase
{
}
公共类ItemChange,其中T:MyBase
{
当{get;set;}时的公共日期时间
公共字符串Who{get;set;}
公共电视台;
国家公共部门;
公共静态显式运算符ItemChange(ItemChange i)
{
返回新的ItemChange{When=i.When,Who=i.Who,NewState=i.NewState,OldState=i.OldState};
}
}
公共类Sub1:MyBase
{
}
公共类Sub2:MyBase
{
}
公共类HelloWorld
{
公共静态void Main(字符串[]args)
{
ItemChange item=新的ItemChange();
ItemChange itemCasted=(ItemChange)项;
}
} 
}

您需要定义一个显式强制转换操作符

using System;
using System.Collections.Generic;
using System.Linq;

namespace brosell
{

public class MyBase
{

}



public class ItemChange<T> where T : MyBase
{
    public DateTime When { get; set; }
    public string Who { get; set; }
    public T NewState;
    public T OldState;

    public static explicit operator ItemChange<MyBase>(ItemChange<T> i)
   {
      return new ItemChange<MyBase> { When = i.When, Who = i.Who, NewState = i.NewState, OldState = i.OldState};
   }

}

public class Sub1: MyBase
{

}

public class Sub2: MyBase
{

}

   public class HelloWorld
   {
    public static void Main(string[] args)
    {
        ItemChange<Sub1> item = new ItemChange<Sub1>();


        ItemChange<MyBase> itemCasted = (ItemChange<MyBase>)item;
        }
   } 
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
名称空间brosell
{
公共类MyBase
{
}
公共类ItemChange,其中T:MyBase
{
当{get;set;}时的公共日期时间
公共字符串Who{get;set;}
公共电视台;
国家公共部门;
公共静态显式运算符ItemChange(ItemChange i)
{
返回新的ItemChange{When=i.When,Who=i.Who,NewState=i.NewState,OldState=i.OldState};
}
}
公共类Sub1:MyBase
{
}
公共类Sub2:MyBase
{
}
公共类HelloWorld
{
公共静态void Main(字符串[]args)
{
ItemChange item=新的ItemChange();
ItemChange itemCasted=(ItemChange)项;
}
} 
}

ItemChange的基类不是
ItemChange
而是
MyBase
ItemChange的基类不是
ItemChange
而是
MyBase
我不想从基类到子类进行分类。我正试着做另一件事way@leora-我不确定你的意思-
MySubclass
MyBase
的子类。我不想从一个基到另一个基进行分类。我正试着做另一件事way@leora-我不确定你的意思-
MySubclass
MyBase
的子类。