'cannot convert from class to 'T' [closed]
I have the following code:
await ProcessBuffer<ChannelItem>(item);
await ProcessBuffer<SiteItem>(item).Wait();
await ProcessBuffer<SiteMailItem>(item).Wait();
private async Task ProcessBuffer<T>(ServiceBusMigratedItemMessage item)
{
System.Collections.Concurrent.ConcurrentQueue<T> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<T>();
switch (type.ToString())
{
case nameof(SiteItem):
buffer.Enqueue(ConvertSiteMessage(item));
break;
case nameof(ChannelItem):
ChannelItem truc = ConvertChannelMessage(item);
buffer.Enqueue(truc);
break;
case nameof(SiteMailItem):
buffer.Enqueue(ConvertSiteMailMessage(item));
break;
}
buffer.Enqueue(something);
It raises this error in line buffer.Enqueue Error CS1503 Argument 1: cannot convert from 'Models.Sites.ChannelItem' to 'T'
or cannot convert from 'Models.Sites.SiteItem' to 'T'
etc...
public class ChannelItem : CacheItem
{
}
private ChannelItem ConvertChannelMessage(ServiceBusMigratedItemMessage migratedItem)
{
}
private SiteMailItem ConvertSiteMailMessage(ServiceBusMigratedItemMessage migratedItem)
{
}
I don't know how to cast and enqueue the channelItem?
Solution 1:[1]
await ProcessBuffer<ChannelItem>(item);
private async Task ProcessBuffer<T>(Someclass item)
{
System.Collections.Concurrent.ConcurrentQueue<T> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<T>();
ChannelItem something= new ChannelItem();
buffer.Enqueue(something);
The above is your original code.
Your code has:
ConcurrentQueue<T> buffer
so only "T's" can be put in the ConcurrentQueue
So you need either:
(1)
Change your ConcurrentQueue generic-type:
ConcurrentQueue<ChannelItem> buffer
or (2) you need to put only T items in your ConcurrentQueue
maybe you mean to code the below?
(note the change to "T item" in the method signature?/
await ProcessBuffer<ChannelItem>(item);
private async Task ProcessBuffer<T>(T item)
{
System.Collections.Concurrent.ConcurrentQueue<T> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<T>();
buffer.Enqueue(item);
or (3) many you mean (and need) to "constrain" the Generic.
await ProcessBuffer<ChannelItem>(item);
private async Task ProcessBuffer<T>(T item) where T : CacheItem
{
System.Collections.Concurrent.ConcurrentQueue<T> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<T>();
buffer.Enqueue(item);
In the above microsoft URL, look for this code sample:
public static void OpEqualsTest<T>(T s, T t) where T : class
{
System.Console.WriteLine(s == t);
}
(You've now edited your question)
or 4
you may need a "marker" interface.
public interface IMyMarker()
{
}
public class ChannelItem : IMyMarker
{
}
public class SiteItem : IMyMarker
{
}
public class SiteMailItem : IMyMarker
{
}
and now constrain T to IMyMarker
private async Task ProcessBuffer<T>(T item) where T : IMyMarker
{
System.Collections.Concurrent.ConcurrentQueue<T> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<T>();
buffer.Enqueue(item);
Here's the bottom line.
If you define a
ConcurrentQueue<T>
you can put ~~only "T's" on it.
you can "constrain" the T's some, but you can never break the rule that "you can put ~only T's" on the
ConcurrentQueue<T>
Solution 2:[2]
System.Collections.Concurrent.ConcurrentQueue<ChannelItem> buffer = null;
buffer = new System.Collections.Concurrent.ConcurrentQueue<ChannelItem>();
Just change the T to ChannelItem
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | DamnScandalous |