2016-04-13 32 views
1

指定子类(或任何类)作为返回类型时应该如何设置Apply方法,以便当我调用它时,可以指定我想要的返回类型BaseResult当调用方法

目的是让调用代码知道是什么子类(实施BaseResult),该应用将返回(再次,考虑到从IRequest调用应用,而不是在它的实现)

的条件:

  • 可能有许多实现IRequest
  • 可能有很多实现的BaseResult

代码

void Main() 
{ 
    // For example purpose, let's pretend 'myreq' is retrieved from reflection. So, there's no way I would know it's type of MyRequest. And there will be many other implementations of IRequest. 
    var req = new MyRequest(); 

    var request = (IRequest)req; 

    // How should I setup Apply method so that when I call the method, I can specify what BaseResult return type that I want? 
    // In this example, I would like Apply method to return Result type, which inherits from BaseResult. 
    var res = req.Apply<Result>(); 
} 

// Define other methods and classes here 
public interface IRequest 
{ 
    string GetValue(); 
    T Apply<T>() where T : BaseResult; 
} 

public class MyRequest : IRequest 
{ 
    // How should I setup Apply method to allow returning any BaseResult I want? Each IRequest implementation of Apply method may return different BaseResult type. 
    public T Apply<T>() where T : BaseResult 
    { 
     // Doesn't work here 
     // Can't implicitly convert type BaseResult to T 
     return (BaseResult) new Result(); 
    } 

    public string GetValue() { return string.Empty; } 
} 

public class Result : BaseResult 
{ 
    public string Message { get; set;} 
} 

public class AnotherResult : BaseResult 
{ 
    public string Message { get; set; } 
} 

public class BaseResult 
{ 
} 
+0

可以约束类型应用''需要一个'新的()'? – AGB

+0

您的代码不是通用的。如果你叫'Apply ',怎么办?你会将一个'Result'投射到'AnotherResult',这在运行时会失败, –

+0

@Dananley,这就是为什么我在这里,寻求其他人的想法和解决我的问题.. :) – stack247

回答

0

在你的应用方法,铸就新的实例为T.

public T Apply<T>() where T : BaseResult 
{ 
    var newInstance = new Result(); 
    return newInstance as T; 
} 
+0

如果'T'是'AnotherResult',这将在运行时失败。 – Enigmativity

+0

@Enigmativity在我的电话中'T'不是'AnotherResult'。即使这样,运算符as也不会在运行时失败。如果返回的对象不是'T'的类型,它只会返回'null'。 – stack247

+0

@ stack247 - 然后通用的点是什么? – Enigmativity

1

你能约束的Apply<T>类型有一个默认的构造函数?

public T Apply<T>() where T : BaseResult, new() 
{ 
    //you could put settable properties on BaseResult 
    //(or similar interface) and set them here, as well. 
    return new T(); 
} 

这也需要您指定接口上的约束:

public interface IRequest 
{ 
    string GetValue(); 
    T Apply<T>() where T : BaseResult, new(); 
} 
+0

您提出的解决方案是返回新的“T”。如果我有'BaseResult'的对象类型,我应该如何返回该对象而不是新的'T'? – stack247

0

您可以更改Apply<T>返回类型BaseResult

public interface IRequest 
{ 
    string GetValue(); 
    BaseResult Apply<T>() where T : BaseResult; 
} 

public class MyRequest : IRequest 
{ 
    public BaseResult Apply<T>() where T : BaseResult 
    { 
     return new Result(); 
    } 

    public string GetValue() { return string.Empty; } 
} 

编辑:想象一下,您需要使用此解决方案进行类型转换,而不是在调用代码中。所以它并不能真正解决问题。

编辑2:实际上,它看起来像返回泛型类型服务于此特定用途 - 以避免在调用代码中投射。鉴于所需的类型在代码Apply中已知,是否真的有必要?

+1

这是一个奇怪的签名 - '公共BaseResult应用()其中T:BaseResult' - 'T'在这里没有做任何有用的事情。 – Enigmativity

+0

嗯,我想它仍然限制呼叫者“请求”一些不是从'BaseResult'派生的类型。虽然我同意这是一种奇怪的泛型应用。 –

+0

@DmitryRotay是的,我的目的是让调用代码知道'Apply'正在返回的子类(BaseResult'的实现)(再次,考虑到从'IRequest'调用'Apply',而不是执行它)。 – stack247

相关问题