Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/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# 将对象强制转换为通用接口_C#_Generics_Interface_Casting - Fatal编程技术网

C# 将对象强制转换为通用接口

C# 将对象强制转换为通用接口,c#,generics,interface,casting,C#,Generics,Interface,Casting,我有以下界面: internal interface IRelativeTo<T> where T : IObject { T getRelativeTo(); void setRelativeTo(T relativeTo); } 内部接口IRelative,其中T:IOObject { T getRelativeTo(); void setRelativeTo(T relativeTo); } 以及一系列(应该)实现它的类,例如: public class A

我有以下界面:

internal interface IRelativeTo<T> where T : IObject
{
    T getRelativeTo();
    void setRelativeTo(T relativeTo);
}
内部接口IRelative,其中T:IOObject
{
T getRelativeTo();
void setRelativeTo(T relativeTo);
}
以及一系列(应该)实现它的类,例如:

public class AdminRateShift : IObject, IRelativeTo<AdminRateShift>
{
    AdminRateShift getRelativeTo();
    void setRelativeTo(AdminRateShift shift);
}
公共类AdminRateShift:IOObject,iRelative
{
AdminRateShift getRelativeTo();
void setRelativeTo(管理班次);
}
我意识到这三者并不相同:

IRelativeTo<>
IRelativeTo<AdminRateShift>
IRelativeTo<IObject>
iRelative
Irelative
Irelative
但尽管如此,我需要一种方法来处理所有不同的类,比如AdminRateShift(以及FXRateShift、DetRateShift),它们都应该实现IRelativevot。假设我有一个函数,它将AdminRateShift作为对象返回:

IRelativeTo<IObject> = getObjectThatImplementsRelativeTo(); // returns Object
IRelativevot=GetObjectthatImplementsRelativevot();//返回对象
通过对接口进行编程,我可以做我需要做的事情,但我实际上无法将对象强制转换为iRelative以便使用它


这是一个微不足道的例子,但我希望它能澄清我的意图。

不幸的是,继承不适用于泛型。如果您的函数需要iRelative,您也可以将函数设置为泛型:

void MyFunction<T>(IRelativeTo<T> sth) where T : IObject
{}
void MyFunction(IRelative sth)其中T:IObject
{}
如果我没记错的话,当您使用上面的函数时,您甚至不需要指定类型,编译器应该根据您提供的参数来计算它

如果您希望在类或方法中保留对其中一个IRelative对象的引用(而您不关心它是什么),则需要再次将该类/方法设置为泛型


我同意,这有点痛苦。

如果我理解这个问题,那么最常见的方法就是声明一个非通用的基本接口,即

internal interface IRelativeTo
{
    object getRelativeTo(); // or maybe something else non-generic
    void setRelativeTo(object relativeTo);
}
internal interface IRelativeTo<T> : IRelativeTo
    where T : IObject
{
    new T getRelativeTo();
    new void setRelativeTo(T relativeTo);
}
而不是

DoSomething<SomeType>(foo);
DoSomething(foo);

这两种方法都有好处。

如果您所关心的只是iRelative处理IObjects,那么您不需要将其设置为通用:

interface IRelativeTo
 {
   IObject getRelativeTo();
   void setRelativeTo(IObject relativeTo)
 }
实现类可能仍然是泛型的,但是:

abstract class RelativeTo<T>  : IRelativeTo where T : IObject
 {  
   public virtual T getRelativeTo() {return default(T);}

   public virtual void setRelativeTo(T relativeTo) {}

   IObject IRelativeTo.getRelativeTo() {return this.getRelativeTo(); }

   void IRelativeTo.setRelativeTo(IObject relativeTo) 
    { this.setRelativeTo((T) relativeTo);
    }
 }

class AdminRateShift :  RelativeTo<AdminRateShift>, IObject {}

嗨,我已经完成了你描述的第一种方法。有没有办法让继承
irelativev
的类也不必实现
irelativev
呢?@dav_i如果你保留了这两个接口,那没什么好遗憾的,你会认为
new
关键字会真的隐藏它。虽然我猜如果你将你的对象转换成非泛型对象,你将不知道该怎么做。。。谢谢
interface IRelativeTo
 {
   IObject getRelativeTo();
   void setRelativeTo(IObject relativeTo)
 }
abstract class RelativeTo<T>  : IRelativeTo where T : IObject
 {  
   public virtual T getRelativeTo() {return default(T);}

   public virtual void setRelativeTo(T relativeTo) {}

   IObject IRelativeTo.getRelativeTo() {return this.getRelativeTo(); }

   void IRelativeTo.setRelativeTo(IObject relativeTo) 
    { this.setRelativeTo((T) relativeTo);
    }
 }

class AdminRateShift :  RelativeTo<AdminRateShift>, IObject {}
  IRelativeTo irt = new AdminRateShift();
  IObject o = irt.getRelativeTo();
  irt.setRelativeTo(o);