2017-12-22 11 views
0

뭔가이처럼 보이는이려고 따라 호출 :C#을 자녀에 대한 상속 정적 속성의 설정 값과 하위 유형

상속의 목적은
class SerialEquipment 
{ 
    private int baudrate; 
    ...... 

    public SerialEquipment(int baudrate) 
    { 
     this.baudrate= baudrate; 
    } 

    public int Baudrate{ get => baudrate; set => baudrate= value; } 
    ...... 

    public static void IdentifyEquipment<EquipmentType>() 
    { 
     int baudrate = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null); 
     ........ 
    } 
} 

class EquipmentTypeA: SerialEquipment 
{ 
    private static readonly int baudrate = 9600; 
    ...... 
    public EquipmentTypeA() : base(baudrate) { } 

    public static new int Baudrate{ get => baudrate} 
    ...... 
} 

class EquipmentTypeB : SerialEquipment 
{ 
    private static readonly int baudrate = 38400; 
    ...... 
    public EquipmentTypeB() : base(baudrate) { } 

    public static new int Baudrate { get => baudrate } 
    ...... 
} 

있지만 중복을 방지하기를 내가 할 수있는 내 사용을 위해 더 나은 것을 찾지 못한다. 선언문을 하나만 가질 수있는 방법을 찾을 수 없습니다. 이것을 구현하는 더 좋은 방법이 있습니까?

편집 2018년 3월 1일 : 여기에 새로운 구현

public static List<String> IdentifyEquipment<EquipmentType>() 
{ 
    List<String> wantedEquipmentList = new List<String>(); 

    int baudrate = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null); 
    String identificationCommand = (int)typeof(EquipmentType).GetProperty("Baudrate", BindingFlags.Static | BindingFlags.Public).GetValue(null, null); 
    String correctIdentificationResponse = (String)typeof(EquipmentType).GetProperty("CorrectIdentificationResponse", BindingFlags.Static | BindingFlags.Public).GetValue(null, null); 

    foreach (String aSerialPort in SerialPort.GetPortNames()) 
    {  
     SerialPort deviceInTest = new SerialPort(aSerialPort, baudrate); 
     deviceInTest.Open(); 

     deviceInTest.WriteLine(identificationCommand); 
     System.Threading.Thread.Sleep(50); 
     string result = deviceInTest.ReadLine(); 

     if (result.StartsWith(correctIdentificationResponse)) 
     { 
      wantedEquipmentList.Add(aSerialPort); 
     }  
    } 

    return wantedEquipmentList; 
}  

와 브루노 Belmonde 솔루션에 관한 :

class DeviceIdentifier 
{ 
    private List<DeviceFactory> factories = new List<DeviceFactory>(); 
    public void AddDeviceType(DeviceFactory factory) => factories.Add(factory); 
    public ISerialDevice BuildDeviceByIdentification(String comPort, int baudrate, String identificationCommand, String identificationResponse) => factories.FirstOrDefault(deviceFactory => IdentifyEquipment(comPort, baudrate, identificationCommand, identificationResponse))?.Builder(); 

    private bool IdentifyEquipment(String comPort, int baudrate, String identificationCommand, String identificationResponse) 
    { 
     bool foundIt = false; 
     SerialPort deviceInTest = new SerialPort(comPort, baudrate); 
     deviceInTest.ReadTimeout = 200; 
     deviceInTest.Open(); 

     try 
     { 
      deviceInTest.WriteLine(identificationCommand); 
      System.Threading.Thread.Sleep(50); 
      string result = deviceInTest.ReadLine(); 
      if (result.StartsWith(identificationResponse)) 
      { 
       foundIt = true; 
      } 
     } 
     catch 
     { 
      //........ 
     } 

     deviceInTest.Close(); 
     return foundIt; 
    } 
} 

// MAIN 
DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); 
List<EquipmentTypeA> typeAList = new List<EquipmentTypeA>(); 

deviceIdentifier.AddDeviceType(new DeviceFactory 
{ 
    Baudrate = 9600, 
    IdentificationCommand = "You are ?", 
    IdentificationResponse = "Type A", 
    Builder =() => new EquipmentTypeA(9600) 
}); 

foreach(String aSerialPort in SerialPort.GetPortNames()) 
{ 
    ISerialDevice identifiedObject = deviceIdentifier.BuildDeviceByIdentification(aSerialPort, 9600, "You are ?", "Type A"); 

    if (identifiedObject != null) 
     typeAList.Add((EquipmentTypeA)identifiedObject); 
} 

기능 장비를 식별하기 위해 정적 사용하여 다음과 같습니다

+0

가장 먼저 떠오르는 질문은 어떻게 사용 하시겠습니까? 대답은 유스 케이스에 따라 달라질 것이다. 정적 메서드를 재정의하면 다형성 컬렉션 (또는 다형성 선언)이있는 경우 작동하지 않으므로 나쁜 선택이 될 수 있습니다. –

+0

차량 휠에 대해 2,3,4,6,10 개의 옵션 만 사용할 수 있습니다. .. 단지 열거 형을 사용하십시오 ... * shrug * –

+0

@BrunoBelmondo이 예제의 값 wheelsNumber는 직렬 장비 (기본 클래스)의 다른 종류 (하위 클래스)의 기본 통신 속도에 해당합니다. 나는 통신 속도와 다른 많은 정적 속성들을 사용하여 내가 말하고있는 장비를 먼저 확인한 다음, 그것을 사용하기 시작했습니다. – Dairon

답변

0

디자인을 다음과 같이 변경하십시오.

(210)

그리고

public interface IDevice 
{ 
    void WhateverIWantToDoWIthDevice(); 
} 

public class DeviceIdentifier 
{ 
    private List<DeviceFactory> factories = new List<DeviceFactory>(); 
    public void AddDeviceType(DeviceFactory factory) => factories.Add(factory); 
    public IDevice BuildDeviceFromBaudrate(int baudrate) => factories.FirstOrDefault(f => f.BaudRate == baudrate)?.Builder(); 
} 

public class DeviceFactory 
{ 
    public int BaudRate { get; set; } 
    public Func<IDevice> Builder { get; set; } 
} 
다음 주, 뭔가가 연결되어있을 때, 그래서 당신은 당신에게 장치의 인스턴스를 줄 것이다 장치 식별자 대 전송 속도를 테스트이

deviceIdentifier.AddDeviceType(new DeviceFactory 
{ 
    BaudRate = 12, 
    Builder =() => new DeviceOfTypeA() 
}); 

처럼 알려진 장치를 추가, assumign에 그 하나의 공장과 일치합니다. 현재 식별하는 데 필요한 테스트부터 정교한 수

... 결국

, 정적 기억은 일반적으로 나쁜 냄새주의하고 너무 많은 정적으로 조작해야합니다. 정적 재정의가 더 악합니다.

+0

이 구현을 시도하고 알려 드리겠습니다. – Dairon

+0

코드에 사용 된 모든 개념을 실제로 얻지는 못합니다. 나는이 객체 생성 과정을 사용하지 않았다. (빌더 패턴?). 그리고 특히이 줄은 : "공용 IDevice BuildDeviceFromBaudrate (int baudrate) => factory.FirstOrDefault (f => f.BaudRate == baudrate)? Builder();" 자세한 설명을 제공해 주시겠습니까? – Dairon

+0

이 라인은 모든 공장을 조사하고 주어진 Baudrate와 일치하는 첫 번째 라인을 얻습니다. 사용 가능한 것이없는 경우는 null를 돌려줍니다. 그렇지 않으면 빌더 함수를 호출합니다 (chich는 팩토리가 보유한 유형의 생성자에 대한 호출을 래핑합니다). –