Maurício Linhares
Maurício Linhares

Reputation: 40333

What can I use here to simulate the ? (wildcard) generic in C#?

I have the following code:

using System;
using System.Collections.Generic;
using SpiShared;

namespace SpiController.Queue
{
    public class FakeQueueService : IQueueService
    {

        public FakeQueueService()
        {
            this.MessagesDeleted = new List<QueueMessage<?>>();
        }

        public IList<QueueMessage<?>> MessagesDeleted {
            get;
            private set;
        }

        public void Delete<T>(QueueMessage<T> message)
        {
            this.MessagesDeleted.Add(message); // doesn't work
        }

    }
}

At Delete I don't actually care what T is, all I care is that I want to store the message object provided. How do I do that with generics here? Is that even possible?

The actual IQueueService interface is:

using System;
using SpiShared;

namespace SpiController.Queue
{
    public interface IQueueService
    {

        Option<QueueMessage<T>> Poll<T>(Func<string,T> parser);

        void Push(string queueUrl, string message);

        void Delete<T>(QueueMessage<T> message);

    }
}

Upvotes: 1

Views: 117

Answers (3)

Batavia
Batavia

Reputation: 2497

since you added a QueueMessage it would seems to me that you can just make your whole class generic based on T

namespace SpiController.Queue
{
  public class FakeQueueService<T> : IQueueService
  {

    public FakeQueueService()
    {
        this.MessagesDeleted = new List<QueueMessage<T>>();
    }

    public IList<QueueMessage<T>> MessagesDeleted {
        get;
        private set;
    }

    public void Delete(QueueMessage<T> message)
    {
        this.MessagesDeleted.Add(message); 
    }

  }
}

Update: The real question becomes why is QueueMessage a strongly typed class. Usually it is because you really know what messages you want to put on a certain queue (Say a particular queue always holds messages containing an invoice)

If you don't want to keep track of the type of message then just use a QueueMessage class. For example if i look at the QueueMessage class used in azure there is a non-generic version available. https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.queue.protocol.queuemessage.aspx

Upvotes: 4

Matt Clark
Matt Clark

Reputation: 1171

As others have suggested, you can use "T" everywhere. Alternatively if you truly want a single list to contain all types you can make the "?" be "object" this will allow effectively any type to be stored there, and cast it later. This is pretty common in the .net libraries.

Alternatively, use "T" everywhere as suggested previously (IE make the entire class generic) but decide on some interface that T should come from, like this:

public class FakeQueueService<T> : IQueueService where T: ISomeInterface

Upvotes: 0

SLaks
SLaks

Reputation: 887479

You can't.

Instead, you can either make your entire class generic (and make Delete() non-generic), or add a non-generic base interface to QueueMessage and store that instead.

Upvotes: 4

Related Questions