функция делегата не видит объект класса - PullRequest
0 голосов
/ 23 октября 2019

Я пытался сделать пример делегата самостоятельно. Имя делегата MaaşKarşılaştırmaDelegesi. Во-первых, я попытался сравнить поля двух объектов (это «maaş») из одного класса (которые либо BeyazYaka, либо MaviYaka), это работало хорошо. Но затем я хотел сравнить два объекта из разных классов (один из MaviYaka и один из BeyazYaka), но затем внутри делегированной функции в классе Program компилятор выдает ошибку, говорящую:

Имя 'k1' не существует в текущем контексте

Имя 'k2' не существует в текущем контексте

Таким образом, компилятор не видит созданный классобъекты. Я думаю, что ошибка в блоке if else. Потому что, когда я пытаюсь удалить блок и просто написать;

MaviYaka k1 = (MaviYaka)o1;

BeyazYaka k2 = (BeyazYaka)o2;

ошибка удаляется. Но выдает ошибку, когда это в блоке if. Можете ли вы помочь мне, почему это происходит?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace tekrar_delegates
{
    class MaviYaka
    {
    public int maaş;

    public MaviYaka(int maaş)
    {
        this.maaş = maaş;
    }

    public static int KiminMaaşıDahaFazla(object o1, object o2) 
    {
        MaviYaka m1 = (MaviYaka)o1;
        MaviYaka m2 = (MaviYaka)o2;

        if (m1.maaş > m2.maaş) { return 1; }
        else { return 2; }
    }

}

class BeyazYaka
{
    public int maaş;

    public BeyazYaka(int maaş)
    {
        this.maaş = maaş;
    }

    public static int KiminMaaşıDahaFazla(object o1, object o2) 
    {
        BeyazYaka b1 = (BeyazYaka)o1;
        BeyazYaka b2 = (BeyazYaka)o2;

        if (b1.maaş > b2.maaş) { return 1; }
        else { return 2; }
    }
}

class Pair
{
    private object[] thePair = new object[2];

    public Pair(object o1, object o2)
    {
        thePair[0] = o1;
        thePair[1] = o2;
    }

    public delegate int MaaşKarşılaştırmaDelegesi(object o1, object o2);

    public void Print(MaaşKarşılaştırmaDelegesi delegatedFunc)
    {
        if (delegatedFunc(thePair[0], thePair[1]) == 1) { Console.WriteLine("1.nin maaşı daha büyük."); }
        else { Console.WriteLine("2.nin maaşı daha büyük."); }
    }

}

class Program
{
    public static int KiminMaaşıDahaFazla(object o1, object o2)
    {
        if (true)
        {
            MaviYaka k1 = (MaviYaka)o1;
        }
        else { }
        if (true)
        {
            BeyazYaka k2 = (BeyazYaka)o2;
        }
        else { }

        if (k1.maaş > k2.maaş) { return 1; }
        else { return 2; }
    }



    static void Main(string[] args)
    {
        MaviYaka maviYaka1 = new MaviYaka(300);            

        BeyazYaka beyazYaka1 = new BeyazYaka(500);            

        Pair karışıkPair = new Pair(maviYaka1, beyazYaka1);            

        Pair.MaaşKarşılaştırmaDelegesi karışıkDelege = new Pair.MaaşKarşılaştırmaDelegesi(KiminMaaşıDahaFazla);

        karışıkPair.Print(karışıkDelege);     

        Console.Read();
    }
}

1 Ответ

0 голосов
/ 23 октября 2019

Когда вы определяете переменную внутри блока if, ее область действия ограничивается этим блоком кода и фактически исчезает, когда этот блок кода заканчивается.

Чтобы избежать этой конкретной ошибки, вы можетеизмените свой код на:

public static int KiminMaaşıDahaFazla(object o1, object o2)
{
    // We need to define k1 and k2 outside of the if block 
    // in order to use them outside of the if block
    MaviYaka k1 = null;
    BeyazYaka k2 = null;

    if (true)
    {
        k1 = (MaviYaka) o1;
    }
    else { }
    if (true)
    {
        k2 = (BeyazYaka) o2;
    }
    else { }

    if (k1.maaş > k2.maaş) { return 1; }
    else { return 2;}
}

Кроме того, нет смысла использовать if (true) { // do something } else {}, хотя я предполагаю, что это есть для некоторых целей тестирования, но весь ваш метод может быть упрощен до одной строки:

public static int KiminMaaşıDahaFazla(object o1, object o2)
{
    return ((MaviYaka)o1).maaş > ((BeyazYaka)o2).maaş ? 1 : 2;
}

Лучшим способом сделать это может быть просто проверка типа o1 и o2 во время выполнения и получение значений свойств от объектов таким образом.

Например:

public static int KiminMaaşıDahaFazla(object o1, object o2)
{
    // I've assumed the type is 'int'; change to the correct type if needed
    int k1_maaş = 0;
    int k2_maaş = 0;

    // Check the type of object and assign our variables as appropriate
    if (o1 is MaviYaka) k1_maaş = ((MaviYaka) o1).maaş;
    else if (o1 is BeyazYaka) k1_maaş = ((BeyazYaka) o1).maaş;

    if (o2 is MaviYaka) k1_maaş = ((MaviYaka) o2).maaş;
    else if (o2 is BeyazYaka) k1_maaş = ((BeyazYaka) o2).maaş;

    return k1_maaş > k2_maaş ? 1 : 2;
}

Другим вариантом является создание интерфейса, который имеет общие свойства между двумя классами, реализация интерфейса для обоих классов, а затем этот метод принимает два аргумента:тип интерфейса:

Например:

public interface ICommonYaka
{
    int maaş { get; set; }
}
public class MaviYaka : ICommonYaka
{
    public int maaş { get; set; }
}
public class BeyazYaka : ICommonYaka
{
    public int maaş { get; set; }
}

Теперь мы можем написать наш метод, подобный этому, и можем передать тип MaviYaka или BeyazYaka (или любой другой класс, которыйинвентарьICommonYaka) на любой аргумент:

public static int KiminMaaşıDahaFazla(ICommonYaka o1, ICommonYaka o2)
{
    return o1.maaş > o2.maaş ? 1 : 2;
}
...