2011-12-14 3 views
3

나는 모두에 공통적 인 몇 가지 속성을 가진 여러 객체를 가지고 있습니다. 예를 들어일반적인 속성을 가진 여러 개체를 사용할 수있는 C# 메서드?

대상물 (A)는 입력 X이며 그것은

객체 B 타입 Y의 10 개 속성

을 가지고 있으며

오브젝트 C가 입력 Z의 15 개 속성

이 있고 7 개 속성

을 갖는다

이러한 개체에는 모두 "이름", "서명"및 "체크섬"속성이 공통으로 있습니다. "이름", "서명"및 "체크섬"속성을 포함하는 모든 형식의 개체를 받아 들일 수있는 정적 도우미 메서드를 만들려고합니다. 그럴 수 있습니까? 아니면 실제로 세 가지 다른 방법이 필요합니까 (하나는 각 유형의 개체를 받아 들일 수 있습니까?)?

EDIT - 가치가있는 부분에 대해서는 웹 서비스를 통해 이러한 객체가 나에게 노출되었음을 언급하지 못했습니다.

+1

이 코드를 "구조적 입력"이라고하며 스칼라와 같은 언어로 제공됩니다. C# 4는 '동적'(* 구조적 타이핑이 아닙니다)을 소개합니다. C#이 슬리브를위한 다른 트릭을 가지고 있는지 전혀 알지 못합니다. 표준 접근 방식은 적절한 인터페이스를 추가하는 것입니다. –

답변

2

이러한 객체는 웹 서비스를 통해 노출되므로 객체의 정의를 제어 할 수 없다고 가정합니다. 그것들은 그대로 있고 공통 기본 클래스 또는 인터페이스로부터 상속받을 수 없습니다. 문제에 대한 제약으로 인해 실제로는 두 가지 옵션 만 있습니다.

C# 4.0 이상을 사용하는 경우 새로운 동적 유형을 사용할 수 있습니다. 이것은 기본적으로 런타임까지 유형 evalutation을 수행하지 않는 객체 참조입니다. 따라서 동적 유형에서 사용하는 속성이나 메소드가 존재하지 않으면 합병 중 오류가 아닌 런타임 오류가 발생합니다.

다른 otpion은 단순히 Object 유형에 대한 참조를 가져 와서 속성 및 메서드를 조작하기 위해 리플렉션을 사용합니다. 잠재적 인 많은 추악한.

저는 C# 4 이상을 사용하지 않고 있습니다. 그런 다음 세 가지 방법으로 갈 것입니다. 일부 코드를 복제 할 수도 있지만 C# 3.5에서 사용해야하는 리플렉션 호출을 따르기가 어렵다는 것보다 훨씬 복잡합니다.

+0

대단히 감사합니다!그것들은 제가 찾고 있었던 제안들입니다! – user685869

8

이러한 속성을 공통 기본 클래스 나 인터페이스로 옮겨서 사용해야합니다.

+0

Doh! 나는이 객체들이 웹 서비스 (SOAP)를 통해 나에게 노출되어 있음을 언급하는 것을 잊었다. 그게 당신의 제안을 바꾸나요? – user685869

+0

서비스를 어떻게 소비하십니까? 그것은 차이를 가져서는 안됩니다. – SLaks

+0

웹 참조를 설정할 때 만든 VS 클라이언트 프록시를 사용하고 있습니다. – user685869

2

입니다. 일반적인 메소드를 포함하는 공통 기본 클래스를 정의하고 기본 객체의 객체 A, B 및 C 하위 클래스를 만드는 경우 가능합니다. 정적 도우미 메서드는 기본 클래스를 매개 변수 형식으로 사용할 수 있으며 모든 하위 형식을 매개 변수 형식으로 전달할 수 있습니다.

2

는 인터페이스는하게하지 않는 그러나 나는 기본 클래스를 피할 것, 당신의 도우미 방법은 다음 물론 일 것이다 ISomeGoodNameForCommonProperies에게

public object MyHelperMethod(ISomeGoodNameForCommonProperies myObject) 
{ 
    ... 
} 

상속 걸릴 것

public interface ISomeGoodNameForCommonProperies 
{ 
    string Name {get;set;} 
    string Signature {get;set;} 
    string Checksum {get;set;} 
} 

public class X : ISomeGoodNameForCommonProperies 
{ 
    string Name {get;set;} 
    string Signature {get;set;} 
    string Checksum {get;set;} 
    ... 
} 

public class Y : ISomeGoodNameForCommonProperies 
{ 
    string Name {get;set;} 
    string Signature {get;set;} 
    string Checksum {get;set;} 
    ... 
} 

public class Z : ISomeGoodNameForCommonProperies 
{ 
    string Name {get;set;} 
    string Signature {get;set;} 
    string Checksum {get;set;} 
    ... 
} 

내가 믿는 당신의 최선의 선택이다 당신이 창조하려고하는 대상에 대한 감각. X, Y 및 Z를 다른 객체의 일부 유형으로 정의 할 수 있습니까? 그렇다면 O를 만들어 내재적으로 만들어야합니다. 공통적으로 가지고있는이 3 가지 속성이 논리적 엔티티를 정의하는 데 충분하지 않지만 실용적인 이유로 그룹화해야하는 경우 인터페이스가 가장 좋습니다.

2

또 다른 옵션으로는 dynamic typing도 있습니다. 이 옵션이 당신을 위해 작동해야하지만, 분명히 다른 사람들이 언급했듯이 인터페이스 나 기본 클래스를 사용하려고합니다.

4

두 가지 좋은 옵션이 있습니다. 첫 번째는 상속입니다 : 당신이 그 속성을 가상 할 수 있기 때문에이 강력 할 수

public class CommonObject 
{ 
    public string Name; 
    public string Signature; 
    public string Checksum; 
} 

public class X : CommonObject 
{ 
    // other properties 
} 

public class Y : CommonObject 
{ 
    // other properties 
} 

public class Z : CommonObject 
{ 
    // other properties 
} 

public static void DoSomething(CommonObject o) 
{ 
    // You can access these values 
    if (o.Name == "" || o.Signature == "") 
     o.Checksum = 0; 
} 

, 각 클래스는 다르게 처리하기 위해 재정의 할 수 있습니다.

두 번째 옵션은 인터페이스를 사용하고 있습니다 :

이 모든 일반적인 속성을 가진 기본 클래스를 만들고 그것에서 다른 사람을 도출 :

public class OtherClass 
{ 
    public static void DoSomething(CommonObject o) 
    { 
     // code here 
    } 
} 

public interface CommonObject 
{ 
    string Name { get; } 
    string Signature { get; } 
    string Checksum { get; } 
} 

public class X : CommonObject 
{ 
    private string _name = ""; 
    private string _signature = ""; 
    private string _checksum = ""; 

    string CommonObject.Name { get { return _name; } } 
    string CommonObject.Signature { get { return _signature; } } 
    string CommonObject.Checksum { get { return _checksum; } } 
} 
+0

메소드는 인터페이스 선언에서 구현을 가질 수 없습니다. 그것은 읽어야합니다 : '정적 무효 DoSomething (CommonObject o); ' –

+0

기술적으로 그것은 내가 게시 한 코드 어디에도 가지 않아야합니다. 그는 정적 도우미 방법을 사용하고 있다고 말했다. 그는 그가 원하는 수업에 넣었습니다. 나는 더미 클래스를 추가했다. –

1

은이 문제에 대한 두 가지 방법이 있습니다.

public abstract class MyBaseClass 
{ 
    public string Name { get; set; } 
    public string Signature { get; set; } 
    public int Checksum { get; set; } 
} 

public class ClassX : MyBaseClass 
{ 
    // Add the other properties here 
} 

public class ClassY : MyBaseClass 
{ 
    // Add the other properties here 
} 

public class ClassZ : MyBaseClass 
{ 
    // Add the other properties here 
} 

형 MyBaseClass의 매개 변수가됩니다 도우미 방법 : 지금은 액세스 할 수 있기 때문에,

public void MyHelperMethod(MyBaseClass obj) 
{ 
    // Do something with obj.Name, obj.Siganture and obj.Checksum 
} 

는 또한 MyBaseClass에서 도우미 메서드를 배치하는 것이 좋습니다 수 있지만 매개 변수가없는 것을 직접 등록 :

public abstract class MyBaseClass 
{ 
    public string Name { get; set; } 
    public string Signature { get; set; } 
    public int Checksum { get; set; } 

    public void CreateChecksum() // Your helper method 
    { 
     Checksum = Name.GetHashCode()^Signature.GetHashCode(); 
    } 
} 

그런 다음 당신은 당신의 객체에서 직접 호출 할 수 있습니다 :

objA.CreateChecksum(); 
objB.CreateChecksum(); 
objB.CreateChecksum(); 

아니면 세 가지 클래스가 구현하는 인터페이스 정의 :

public interface IMyInterface 
{ 
    string Name { get; set; } 
    string Signature { get; set; } 
    int Checksum { get; set; } 
} 

public class ClassX : IMyInterface 
{ 
     public string Name { get; set; } 
     public string Signature { get; set; } 
     public int Checksum { get; set; } 
    // Add the other properties here 
} 

public class ClassY : IMyInterface 
{ 
     public string Name { get; set; } 
     public string Signature { get; set; } 
     public int Checksum { get; set; } 
    // Add the other properties here 
} 

public class ClassZ : IMyInterface 
{ 
     public string Name { get; set; } 
     public string Signature { get; set; } 
     public int Checksum { get; set; } 
    // Add the other properties here 
} 

도우미 방법은 형 IMyInterface의 매개 변수가됩니다 :

public void MyHelperMethod(IMyInterface obj) 
{ 
    // Do something with obj.Name, obj.Siganture and obj.Checksum 
} 

당신은 같은 MyHelperMethod를 호출 할 수 있습니다

MyHelperMethod(objA); 
MyHelperMethod(objB); 
MyHelperMethod(objC); 
관련 문제