English 中文(简体)
Can I force an implementing class to return an object of its own type?
原标题:
  • 时间:2009-11-06 15:22:57
  •  标签:
  • c#
  • interface

I want to make an interface in C# that defines a method that always returns an object of the implementing class, thus:

public interface IParser {
    IParser Parse(string s);
}

public class Parser : IParser {
    public Parser Parse(string s) {
        return new Parser(s);
    }
}

Can I force an implementing class to return an object of its own type? If possible, then how? Or is generics the answer here?

NB: The code is just an illustration, not something that s supposed to run.

最佳回答

Generics is the answer here.

public interface IParser<T> where T:IParser<T> {
    T Parse(string s);
}

public class Parser : IParser<Parser> {
    public Parser Parse(string s) {
        return new Parser(s);
    }
}
问题回答

Not in the interface declaration, no. The best you could manage is with generics:

public interface IParser<T>
    where T: IParser<T>
{
    T Parse(string s);
}

public class Parser
 : IParser<Parser>
{
    public Parser Parse(string s)
    {
       return new Parser(s);
    }
}

This doesn t force the implementation to return it s own type, but at least it allows it to do so. This is why the IClonable interface returns an object from its Clone method, rather than a specific type.

----Edit----

Something to remember on this question: let s say that my code, for which you don t have any knowledge of the implementation, returns an IParser, and your code calls the Parse method. What object do you expect to be returned, not knowing the concrete type of returned IParser reference? I think you re trying to use interfaces for something they re not meant to do...

Yes, and this is known as the factory pattern, only that usually this is complemented with the use of a private constructor and making the instance returning method static, for example:

public class Parser : IParser {

    private Parser(string s) {
        //Do something with s, probably store it in a field
    }

    public static IParser GetNewParser(string s) {
        return new Parser(s);
    }
}

You can do this with Generics, but I would probably stick with returning an instance of the interface. Note that since the class implements the interface, returning an instance of it is ok -- it will be an instance of that type and of the interface as well.

public class Parser : I Parser
{
   public IParser Parser( string s )
   {
       return Parser(s);
   }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签