2017-06-15 107 views
2

这可能是一个关于基础设计的问题。声明对象类型的接口

我想对神秘对象执行操作,只要它实现我的接口IMyInterface即可。而且我想由interace定义为返回神秘对象,因此实例的方法之一...

IMyInterface 
    { 
    object GetInstance(); 
    } 

public class MysteryObject : IMYInterface 
} 
    public object GetInstance() 
    { 
     MysteryObject instance = new MysteryObject(); 
     return instance; 
    } 
} 

但这会导致不必要的“对象”类型以及与这些相关的开销。 C#特别使用泛型来杀死这个开销。这将是理想的做这样的事情:

IMyInterface 
    { 
    T GetInstance<T>(); 
    } 

public class MysteryObject : IMYInterface 
} 
    public MysteryObject GetInstance<MysteryObject>() 
    { 
     MysteryObject instance = new MysteryObject(); 
     return instance; 
    } 
} 

我知道这第二个例子不起作用。我知道语法是错误的。 ..但我想知道是否有更好的方法来要求实现IMyInterface的对象返回它自己类型的实例。

我的例子有点不可思议,但我认为大多数人会理解情绪。奇怪的是,我发现很少有这方面的例子或问题。

+0

,几乎铸造引用类型为对象来回 –

回答

4

你可以只是把返回类型IMyInterface

public interface IMyInterface 
{ 
    IMyInterface GetInstance(); 
} 

public class MysteryObject : IMyInterface 
{ 
    public IMyInterface GetInstance() 
    { 
     MysteryObject instance = new MysteryObject(); 
     return instance; 
    } 
} 

或者泛型:

public interface IMyInterface<T> 
{ 
    T GetInstance(); 
} 

public class MysteryObject : IMyInterface<MysteryObject> 
{ 
    public MysteryObject GetInstance() 
    { 
     MysteryObject instance = new MysteryObject(); 
     return instance; 
    } 
} 

如果你想在一般的参数为类型IMyInterface的添加约束这样的:

public interface IMyInterface<T> 
    where T : IMyInterface<T> 
{ 
    T GetInstance(); 
} 

更新

下面是一些示例用法,看看这两个版本之间的区别是什么:

  1. 返回接口IMyInterface

    IMyInterface a = new MysteryObject().GetInstance(); // valid 
    MysteryObject b = new MysteryObject().GetInstance();// invalid 
    MysteryObject b = (MysteryObject)new MysteryObject().GetInstance(); // valid 
    
  2. 从接口返回的泛型类型参数:

    IMyInterface<MysteryObject> a = new MysteryObject().GetInstance(); //valid 
    MysteryObject b = new MysteryObject().GetInstance(); //valid 
    
+0

全面的开销。很好的答案。返回IMyInterface或Generic之间的成本有什么特别的区别? –

+0

通用版本将直接转换为指定的泛型类型参数。例如,如果你要返回接口,你必须手动将其转换为“MysteryObject”。 – Deadzone

+0

@JamieMarshall我在答案中包含了一些例子。 – Deadzone

2

差不多有它。你需要让整个界面通用:

IMyInterface<T> 
    { 
    T GetInstance(); 
    } 

public class MysteryObject : IMYInterface<MysteryObject> 
} 
    public MysteryObject GetInstance() 
    { 
     MysteryObject instance = new MysteryObject(); 
     return instance; 
    } 
}