Ввод полиморфных значений с несколькими интерфейсами в C#

Используйте Отличительное имя для вхождения в систему. "CN=Your user,CN=Users,DC=b2t,DC=local" Это должно работать над любой системой LDAP, включая AD

5
задан Dario 10 December 2009 в 17:00
поделиться

3 ответа

Вы можете выполнить параметрический полиморфизм , как в C #, но не полиморфизм подтипа . То есть, вы можете создать полиморфный метод, например:

void Foo<T>(T t) where T : IFoo, IBar
{
  t.Foo();
  t.Bar();
}

, а затем вы должны передать объект, тип которого известен во время компиляции, чтобы реализовать как IFoo, так и IBar.

Но нет способа сказать

void Foo(IFoo-and-IBar t) 
{
  t.Foo();
  t.Bar();
}

, а затем передать значение, которое одновременно является IFoo и IBar. Отличная функция, но мы не поддерживаем ее.

7
ответ дан 14 December 2019 в 04:39
поделиться

Well, as Eric Lippert said, there's no IFoo-and-IBar type you can use as a method parameter type.

However, I was playing around with some ideas and came up with an alternate way of using your wrapper class that may be better. I'll leave that up to you (or whoever else might search for this question) to decide:

CLASSES

public abstract class ABWrapper : IA, IB
{
    private readonly IA a;
    private readonly IB b;

    protected ABWrapper( IA a, IB b ) { this.a = a; this.b = b; }

    // Implement methods on IA and IB
}

public sealed class ABWrapper<T> : ABWrapper
    where T : IA, IB
{
    private ABWrapper( T a, T b ) : base( a, b ) { }

    public static implicit operator ABWrapper<T>( T t )
    {
        if ( t == null ) return null;
        return new ABWrapper<T>( t, t );
    }
}

EXAMPLE

public class AB : IA, IB { }

void Method( ABWrapper x )
{
}

void Main()
{
    AB x = null;
    Method( (ABWrapper<AB>) x );
}

The icky thing about this is that you need to do a cast to ABWrapper at every call site. You could also create an extension method ABWrapper ToABWrapper(this T t) where T : IA, IB to replace the cast if that would be more preferable.

It would be cool if the compiler could reason that an implicit conversion from AB to ABWrapper exists via implicit conversions to and from ABWrapper. There's probably a very good reason it doesn't try to do that, however.

However, what you gain is the ability to put ABWrapper all throughout your method parameters without needing to genercize the methods.

1
ответ дан 14 December 2019 в 04:39
поделиться

Я не понимаю, зачем вам это нужно. Если бы вы это сделали, вы могли бы объявить базовый интерфейс:

interface AorB {}

interface A : AorB {
    void DoA();
}

interface B : AorB {
    void DoB();
}

и сохранить его в коллекции. Конечно, при извлечении вам придется быть или как приведенное (здесь могут помочь стандартные методы расширения).

Мне кажется, что это возможное нарушение SRP, и коллекция делает слишком много. С другой стороны, интерфейсы слишком мелкие.

0
ответ дан 14 December 2019 в 04:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: