Как реализовать такие функции, как шаблон в C # - PullRequest
0 голосов
/ 06 мая 2018

Как я могу реализовать такие функции, как шаблон в C #? Например, функции FuncA, FuncB и FuncC принимают одинаковые аргументы, а затем эти функции всегда выполняют одну и ту же операцию с ClassA. Даже если эти функции принимают ClassB или три целых числа, эти функции преобразуют ClassB или три целых числа в ClassA для выполнения той же операции, что и при использовании ClassA в качестве аргумента. Я не уверен, что есть хороший способ, но если вы знаете, пожалуйста, дайте мне знать.

void FuncA(ClassA a)
{
    // do something
}
void FuncA(ClassB b)
{
    FuncA(b.ToA());
}
void FuncA(int x, int y, int z)
{
    FuncA(new ClassA(x, y, z));
}

void FuncB(ClassA a)
{
    // do something
}
void FuncB(ClassB b)
{
    FuncB(b.ToA());
}
void FuncB(int x, int y, int z)
{
    FuncB(new ClassA(x, y, z));
}

void FuncC(ClassA a)
{
    // do something
}
void FuncC(ClassB b)
{
    FuncC(b.ToA());
}
void FuncC(int x, int y, int z)
{
    FuncC(new ClassA(x, y, z));
}

// FuncD, FuncE and so on...

Ответы [ 3 ]

0 голосов
/ 06 мая 2018

Это может быть не то, что вы ищете, однако это может дать вам кое-что подумать

public class MyBase
{
   public int X { get; set; }
   public int Y { get; set; }
   public int Z { get; set; }
   public void MethodA()
   {

   }
   public void MethodB()
   {

   }
   public void MethodC()
   {

   }
}

public class ClassA : MyBase
{
   public ClassA()
   {

   }
   public ClassA(int x, int y, int z)
   {
      X = x;
      Y = y;
      Z = z;
   }
}
public class ClassB : MyBase
{

}

Использование

var classA = new ClassA(23,56,324);
classA.MethodA();
classA.MethodB();
classA.MethodC();

var classB = new ClassB();
classB.MethodA();
classB.MethodB();
classB.MethodC();
0 голосов
/ 06 мая 2018

Я решил эту проблему с помощью неявного преобразования и кортежа.

class ClassA
{
    // members...

    public static implicit operator ClassA(ClassB b)
    {
        return b.ToA();
    }

    public static implicit operator ClassA(Tuple<int, int, int> t)
    {
        return new ClassA(t.Item1, t.Item2, t.Item3);
    }
}

void FuncA(ClassA a)
{
    // do something
}
// we don't have to implement overloaded FuncA functions that take ClassB or three integers.
void FuncB(ClassA a) { /* do something */ }
void FuncC(ClassA a) { /* do something */ }
0 голосов
/ 06 мая 2018

Я представляю пару вариантов для этого ...

Вы можете создать базовый класс:

public abstract class ActionerOnA
{
    public abstract void Execute(A a);

    public void Execute(B b) => Execute(b.ToA());
    public void Execute(int x, int y, int z) => Execute(new A(x, y, z));
}

public class Action1 : ActionerOnA
{
    public override void Execute(A a)
    {
        DoSomethingHereWith(a);
    }

    // no need to worry about the other overloads
}

Вы бы использовали это с:

var actionerOnA = new Action1();
actionerOnA(a);
actionerOnA(b);
actionerOnA(x, y, z);

Вы можете использовать вспомогательный класс, в котором зависимость перемещается в конструктор, а не в методы:

public class ActionerOnA
{
    private A _a;
    private Action<A> _actionToExecute;

    public ActionerOnA(Action<A> action, A a) 
    {
        _a = a;
        _actionToExecute = action;
    }

    public ActionerOnA(Action<A> action, B b) : this(action, b.ToA()) { }
    public ActionerOnA(Action<A> action, int x, int y, int z) : this(action, new A(x, y, z)) { }
}

Затем вы бы использовали это как:

var actionerOnA = new ActionerOnA(Func1, a);
var actionerOnA = new ActionerOnA(Func1, b);
var actionreOnA = new ActionerOnA(Func1, x, y, z);

actionerOnA.Execute();

public void Func1(A a) { }
...