Can I restrict a generic method to more than one interface?

I have a general method

public static void DoSomething<T>()
{...}

. Now I want to limit T.

public static void DoSomething<T>() where T: IInterface1
{...}

But I really want some interfaces, something like

public static void DoSomething<T>() where T: IInterface1, IInterface2
{...}

But that does not work. The compiler says something like

There is no implicit conversion from IInterface1 to IInterface2

There is no implicit conversion from IInterface2 to IInterface1

I thought about letting classes implement a common interface that I can access, but I don't have access to classes.

What features can I enable for multiple interfaces?

Thanks Tobi

Edit: This is what I wanted to do. I am developing Outlook-Add-In. I often use this piece of code.

    public static object GetItemMAPIProperty<T>(AddinExpress.MAPI.ADXMAPIStoreAccessor adxmapiStoreAccessor, object outlookItem, uint property) where T: Outlook.MailItem, Outlook.JournalItem
    {
        AddinExpress.MAPI.MapiItem mapiItem;
        mapiItem = adxmapiStoreAccessor.GetMapiItem(((T)outlookItem));
        return mapiItem != null ? mapiItem.GetProperty(property) : null;
    }

GetMapiItem , Outlook (, , ,...). T. , , Outlook.MAPIFolder.

.

    public static object GetItemMAPIProperty<T>(AddinExpress.MAPI.ADXMAPIStoreAccessor adxmapiStoreAccessor, T outlookItem, uint property)
    {
        AddinExpress.MAPI.MapiItem mapiItem;
        mapiItem = adxmapiStoreAccessor.GetMapiItem(((T)outlookItem));
        return mapiItem.GetProperty(property);
    }

( I) , GetMapiItem . , . , , , ( OR) .

+5
6

Interface1 Interface2 . :

    public static void DoSomething<T>() where T : ICommon
    {
        //...
    }

    public interface IInterface1 : ICommon
    {}

    public interface IInterface2 : ICommon
    { }

    public interface ICommon
    { }

, DoSomething() , , ICommon.

: , . , ...

    protected static class DoSomethingServer<T1> where T1 : class
    {

        //Define your allowed types here
        private static List<Type> AllowedTypes = new List<Type> {
            typeof(IInterface1),
            typeof(IInterface2)
        };

        public static MethodInvoker DoSomething()
        {
            //Perform type check
            if (AllowedTypes.Contains(typeof(T1)))
            {
                return DoSomethingImplementation;
            }
            else
            {
                throw new ApplicationException("Wrong Type");
            }
        }

        private static void DoSomethingImplementation()
        {
            //Actual DoSomething work here
            //This is guaranteed to only be called if <T> is in the allowed type list
        }
    }

:

DoSomethingServer<IInterface1>.DoSomething();

, , , . , .

+3

:

interface I1 { int NumberOne { get; set; } }
interface I2 { int NumberTwo { get; set; } }

static void DoSomething<T>(T item) where T:I1,I2
{
    Console.WriteLine(item.NumberOne);
    Console.WriteLine(item.NumberTwo);
}

, ... , - , .

+2

, I1, I2, , (.. ) .

( nader!):

    interface I1 { int NumberOne { get; set; } }
    interface I2 { int NumberTwo { get; set; } }

    static void DoSomething<T>(T item) where T : I1
    {
        Console.WriteLine(item.NumberOne);
    }

    static void DoSomething<T>(T item) where T : I2
    {
        Console.WriteLine(item.NumberTwo);
    }

    static void DoSomething<T>(T item) where T : I1, I2
    {
        Console.WriteLine(item.NumberOne);
        Console.WriteLine(item.NumberTwo);
    }

. , # , / .

.

+2

- , : Interface1 2. .

java; , #

, .

tobi: P

+1
    public interface IInterfaceBase
    {

    }
    public interface IInterface1 : IInterfaceBase
    {
      ...
    }
    public interface IInterface2 : IInterfaceBase
    {
      ...
    } 

    public static void DoSomething<T>() where T: IInterfaceBase
    {
    }

, T IInterface1 IInterface2,

+1

Building what Erwicker said ... names are not the only way. You can also change method signatures ...

public interface I1 { int NumberOne { get; set; } }
public interface I2 { int NumberTwo { get; set; } }

public static class EitherInterface
{
    public static void DoSomething<T>(I1 item) where T : I1
    {
        Console.WriteLine("I1 : {0}", item.NumberOne);
    }

    public static void DoSomething<T>(I2 item) where T : I2
    {
        Console.WriteLine("I2 : {0}", item.NumberTwo);
    }
}

What when testing:

public class Class12 : I1, I2
{
    public int NumberOne { get; set; }
    public int NumberTwo { get; set; }
}

public class TestClass
{
    public void Test1()
    {
        Class12 z = new Class12();
        EitherInterface.DoSomething<Class12>((I1)z);
        EitherInterface.DoSomething<Class12>((I2)z);
    }
}

Sets this output:

I1 : 0
I2 : 0

This is consistent with the purpose of exposing the method name to the caller, but does not help you, since you are not using parameters.

0
source

All Articles