C #: assign instance of child class to interface implemented by abstract class

public interface IParser<T> where T: new()
{
    IList<T> Parse();
}

The following abstract class is implemented over the interface.

public abstract class BaseParser<T>: IParser<T> where T : new()
{
   protected abstract string Sql { get;}
   public List<T> Parse()
   {
      // do parsing
      Console.WriteLine(Sql);
   }
}

Below are two specific implementations of the above abstract class

public class EMailParser: BaseParser<Email>
{
    protected override string Sql
    {
        get
        {
            return @"SELECT * FROM emails";
        }
    }
}

public class UrlParser : BaseParser<Url>
{
    protected override string Sql
    {
        get
        {
            return @"SELECT * From Url";
        }
    }
}

Using:

class Program
{
    static void Main(string[] args)
    {
       if(args[1] == "url")
          Parser<Url>();
       else
          Parser<Email>();
    }
    static void Parse<T>()
    {
       // Create instance based on typof T and then assign to implementaion
       IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser(): new EmailParser();
       parser.Parse();
    }
}

I want to create an instance of the database EmailParseror UrlParserfor the general type provided in Program.Main, and assign it to the interface implemented BaseParser(abstract class). How can i do this? I know I can solve this problem by changing Program.Parse<T>as follows

static void Parse<T>() where T: new()
{
    IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser() as BaseParser<T> : new EmailParser() as BaseParser<T>;
    parser.Parse();
}

However, I want to know why I cannot assign an instance of a child class to an interface implemented by an abstract class?

I do not understand why the next line does not work

IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser(): new EmailParser();

and why does this line work

IParser<T> parser = typeof(T) == typeof(Url) ? new UrlParser() as BaseParser<T> : new EmailParser() as BaseParser<T>;

@nawfal, , BaseParser BaseParser - . IParser BaseParser?

+4
3

UrlParser EmailParser. BaseParser<Url> BaseParser<Email> ( IParser<Url> IParser<Email>) , .

, . - ( ):

static Dictionary<string, Type> typeInfos = new Dictionary<string, Type> 
{
    { "url", typeof(Url) },
    { "email", typeof(Email) },
    // and so on
};

,

class Program
{
    static void Main(string[] args)
    {
        Parse(args[1]);
    }

    static void Parse(string type)
    {
        var parserType = typeof(BaseParser<>)
            .Assembly // or whatever the assembly is
            .GetTypes()
            .First(t => t.BaseType?.GetGenericArguments().FirstOrDefault() == typeInfos[type]);
        dynamic parser = Activator.CreateInstance(parserType);
        parser.Parse();
    }
}

/ , .

: , BaseParser<T> BaseParser<T> - . T . , new UrlParser() as BaseParser<T>. - , as. # ( , ).

+2

, , ,   ?:   . ,?: , , .

: 7.14 # 5.0:

x y ?: . x X, y Y :

  • (§6.1) X Y, Y X, Y .

  • Y X (§6.1), X Y, X .

  • , .

+4

You can use dynamic dispatch:

static IParser<Url> CreateParser(Url uri)
{
    return new UrlPaqrser<Url>();
}

static IParser<Email> CreateParser(Email mail)
{
    return new EmailPaqrser<Email>();
}

static void Main(string[] args)
{
    dynamic t = new Url();
    var parser = CreateParser(t); // invokes CreateParser(Url uri)

    t = new Email();
    parser = CreateParser(t);  // invokes CreateParser(Email email)
}
+1
source

All Articles