Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

c# - How to get actual type of an derived class from its parent interface

Let's say we have a code portion like this:

IProduct product = ProductCreator.CreateProduct(); //Factory method we have here
SellThisProduct(product);

//...

private void SellThisProduct(IProduct product)
{
  //.. Do something here
}

//...

internal class Soda : IProduct
{}

internal class Book : IProduct
{}

How can I infer which product is actually passed into SellThisProduct() method in the method?

I think if I say GetType() or something it will probably return the IProduct type.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

GetType gets you the exact runtime type of an object. From the documentation:

The Type instance that represents the exact runtime type of the current instance.

You can also use is to determine if an object is an instance of a specific type:

var noise = (obj is Velociraptor) ? "SKREEE!" : "<unknown>";

Why do you need the exact runtime type, though? The entire point of an interface is that you should be hiding the implementation details behind the common interface. If you need to take an action based on the type, that's a big hint that you're violating the encapsulation it provides.

One alternative is to use polymorphism:

public interface IVocalizer { string Talk(); }

public class Doorbell : IVocalizer {
  public string Talk() { return "Ding-dong!" }
}
public class Pokemon : IVocalizer {
  public string Talk() {
    var name = this.GetType().ToString();
    return (name + ", " + name + "!").ToUpper(); } // e.g., "PIKACHU, PIKACHU!"
}
public class Human : IVocalizer {
  public string Talk() { return "Hello!"; }
}

Since these three types aren't related at all, inheritance from a common type doesn't make sense. But to represent that they share the same capability of making noise, we can use the IVocalizer interface, and then ask each one to make a noise. This is a much cleaner approach: now you don't need to care what type the object is when you want to ask it to make a noise:

IVocalizer talker = new ???();  // Anything that's an IVocalizer can go here.

// elsewhere:
Console.WriteLine(talker.Talk());    // <-- Now it doesn't matter what the actual type is!
                                     //   This will work with any IVocalizer and you don't
                                     //   need to know the details.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...