Я могу ограничить общий метод больше чем для одного интерфейса?

Лучший подход, который я знаю, должен сделать обновление, сопровождаемое вставкой. "Наверху выбора" необходимо, но это не ужасная нагрузка, так как Вы ищете на первичном ключе, который быстр.

необходимо быть в состоянии изменить ниже операторов с таблицей & имена полей, чтобы сделать то, что Вы хотите.

--first, update any matches
UPDATE DESTINATION_TABLE DT
SET
  MY_FIELD1 = (
              SELECT MY_FIELD1
              FROM SOURCE_TABLE ST
              WHERE ST.PRIMARY_KEY = DT.PRIMARY_KEY
              )
 ,MY_FIELD2 = (
              SELECT MY_FIELD2
              FROM SOURCE_TABLE ST
              WHERE ST.PRIMARY_KEY = DT.PRIMARY_KEY
              )
WHERE EXISTS(
            SELECT ST2.PRIMARY_KEY
            FROM
              SOURCE_TABLE ST2
             ,DESTINATION_TABLE DT2
            WHERE ST2.PRIMARY_KEY = DT2.PRIMARY_KEY
            );

--second, insert any non-matches
INSERT INTO DESTINATION_TABLE(
  MY_FIELD1
 ,MY_FIELD2
)
SELECT
  ST.MY_FIELD1
 ,NULL AS MY_FIELD2  --insert NULL into this field
FROM
  SOURCE_TABLE ST
WHERE NOT EXISTS(
                SELECT DT2.PRIMARY_KEY
                FROM DESTINATION_TABLE DT2
                WHERE DT2.PRIMARY_KEY = ST.PRIMARY_KEY
                );
6
задан Tobias 29 July 2009 в 07:18
поделиться

6 ответов

Это хорошо для меня компилируется:

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);
}

Итак, синтаксис кажется прекрасным ... возможно, что-то еще вызывает проблема.

3
ответ дан 10 December 2019 в 00:42
поделиться

Интерфейс 1 и интерфейс 2 являются производными от одного и того же базового интерфейса. Пример:

    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
ответ дан 10 December 2019 в 00:42
поделиться

Если вы имеете в виду, что параметр может быть либо реализацией 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);
    }

Это дало бы компилятору возможность обрабатывать все возможности без двусмысленности. Но чтобы помочь с управлением версиями, C # пытается избежать ситуаций, когда добавление / удаление метода изменит применимость другого метода.

Вам необходимо написать два метода с разными именами для обработки двух интерфейсов.

2
ответ дан 10 December 2019 в 00:42
поделиться

один из способов - создать дополнительный интерфейс, который расширяет оба, Interface1 и 2. затем вы помещаете этот интерфейс вместо другого 2.

это один из способов сделать это в java; Если я правильно помню, это должно работать и в C #

, надеюсь, что это поможет.

С уважением, Тоби: P

1
ответ дан 10 December 2019 в 00:42
поделиться
    public interface IInterfaceBase
    {

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

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

Если вы хотите, чтобы T был IInterface1 или IInterface2, используйте приведенный выше код

1
ответ дан 10 December 2019 в 00:42
поделиться

Основываясь на том, что сказал Эрвикер ... имена - не единственный путь. Вы также можете изменять сигнатуры методов ...

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);
    }
}

Что при тестировании следующим образом:

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);
    }
}

Дает следующий результат:

I1 : 0
I2 : 0

Это соответствует цели раскрытия единственного имени метода для вызывающего, но не помогает вам, поскольку вы не используете параметры.

0
ответ дан 10 December 2019 в 00:42
поделиться
Другие вопросы по тегам:

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