接受具有公共属性的多个对象的C#方法?

时间:2011-12-14 19:16:48

标签: c# .net methods structural-typing

我有几个具有所有属性共有的属性的对象。例如:

对象A的类型为X,它有10个属性

对象B的类型为Y,它有15个属性

对象C的类型为Z,它有7个属性

所有这些对象都有共同的“名称”,“签名”和“校验和”属性。我正在尝试创建一个静态帮助器方法,该方法可以接受包含“name”,“signature”和“checksum”属性的任何类型的对象。这是可能的还是我实际上需要三种不同的方法(一种接受每种类型的对象)?

编辑 - 对于它的价值,我没有提到这些对象是通过网络服务向我公开的。

8 个答案:

答案 0 :(得分:8)

您应该将这些属性移动到公共基类或接口并使用它。

答案 1 :(得分: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; } }
}

答案 2 :(得分:2)

可能...如果您定义包含公共方法的公共基类,并创建基础的对象A,B和C子类。然后,您的静态辅助方法可以使用基类作为其参数类型,并且可以将任何子类型传递给它。

答案 3 :(得分:2)

我相信界面是你最好的选择,

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

你的帮助方法然后,将采用ISomeGoodNameForCommonProperies

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

继承当然会起作用,但是我会避免使用基类,除非它对你想要创建的对象有意义。你应该问自己的问题,可以将X,Y和Z定义为某种类型的不同对象O吗?如果是这样,继续创造O和固有的。如果您共同拥有的这3个属性不足以定义逻辑实体,但出于实际原因需要将它们组合在一起,那么界面是您的最佳选择。

答案 4 :(得分:2)

另一种选择还有dynamic typing。虽然这个选项适合你,但我肯定会尝试使用其他人提到的接口或基类。

答案 5 :(得分:2)

我将假设由于这些obejcts是通过Web服务公开的,因此您无法控制对象的定义。它们就是它们,你不能让它们从公共基类或接口继承。有了这个问题的约束,你真的只有两个选择。

如果您使用的是C#4.0或更高版本,则可以使用新的动态类型。这基本上是一个对象引用,直到运行时才进行任何类型的评估。因此,如果您在动态类型上使用的属性或方法不存在,您将在compliation期间获得运行时错误而不是错误。

另一个otpion将简单地引用类型Object并使用反射来操作属性和方法。那里有很多潜在的丑陋。

我不使用C#4+然后我想我会采用三种单独的方法。虽然你可能会复制一些代码,但我宁愿拥有一些复杂的难以跟踪的反射调用,你必须在c#3.5中使用 -

答案 6 :(得分:1)

您可以使用inheritance

答案 7 :(得分: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);