C# 如果我给一个类添加更多的方法,每个实例会占用更多的空间吗?

C# 如果我给一个类添加更多的方法,每个实例会占用更多的空间吗?,c#,performance,C#,Performance,作为一名程序员,您总是可以选择向类添加方法,或者创建将该对象的类实例作为参数的相同方法 一种方法是: List<Car> Oldtimers = new List<Car>(); class Car { int speed; int size; public bool IsBig(){ return size >5; } public bool isFast(){ return speed > 1

作为一名程序员,您总是可以选择向类添加方法,或者创建将该对象的类实例作为参数的相同方法

一种方法是:

List<Car> Oldtimers = new List<Car>();    
class Car { 
   int speed; 
   int size;

   public bool IsBig(){
      return size >5;
   }

   public bool isFast(){
   return speed > 120;
   }
}
List Oldtimers=new List();
类汽车{
整数速度;
整数大小;
公共图书馆很大{
返回大小>5;
}
公共bool isFast(){
返回速度>120;
}
}
或者你也可以这样节省空间

class CarCollection {
   List<Car2> Supercars = new List<Car2>();

    class Car2{ 
        public int speed; 
        public int size;
    }

    bool IsBig(Car2 car){
        return car.size > 5
    }

    bool isFast(Car2 car){
       return car.speed > 120;
    }
}
类CarCollection{
List Supercars=newlist();
类Car2{
公共交通速度;
公共整数大小;
}
bool IsBig(Car2车){
返回车。尺寸>5
}
布尔伊斯法斯特(Car2轿车){
返回车速度>120;
}
}
由于没有附加方法,Car2实例现在实际占用的空间是否比Car少?哪个列表更好?字节码之间有差异吗

我还想知道标准是什么,或者是否存在一些我没有看到的性能问题

谢谢你的帮助

Car2实例现在是否比Car实例占用更少的空间,b

没有

每个实例都有一个指向其类型的指针,以及附加的一些其他信息。
但即使使用虚拟方法,这种开销也是固定的


只有字段会占用实例内部的空间。

如果确实需要为每个实例保存字节,则可以切换到存储数据的结构列表,并具有访问数据的管理器类,如示例中所示。棘手的部分是当汽车被拆除时。您还可以考虑使用较小的数字类型,如short或byte。以下是一个例子:

public struct CarHandle
{
    internal int m_id;

    internal CarHandle(int id)
    {
        m_id = id;
    }
    public int ID { get { return m_id; } }
}


public class CarManager
{
    private struct CarData
    {
        public int Speed;
        public int Size;
    }

    private List<CarData> m_cars = new List<CarData>();
    private List<int> m_removedCars = new List<int>();

    public CarHandle CreateCar(int speed, int size)
    {
        var carData = new CarData() { Speed = speed, Size = size };
        // see if there is an empty slot we can use
        if (m_removedCars.Count > 0)
        {
            int ix = m_removedCars[m_removedCars.Count - 1];
            m_removedCars.RemoveAt(m_removedCars.Count - 1);
            m_cars[ix] = carData;
            return new CarHandle(ix);
        }
        else
        {
            m_cars.Add(carData);
            return new CarHandle(m_cars.Count-1);
        }
    }

    public void RemoveCar(ref CarHandle handle)
    {
        if (m_cars.Count > handle.ID && m_cars[handle.ID].Size != -1)
        {

            // remove from list if it is the last car in list
            if (handle.ID == m_cars.Count - 1)
            {
                m_cars.RemoveAt(m_cars.Count - 1);
            }
            else
            {
                // if we remove this item from the list, it would invalidate 
                // all handles after this index, so we just remember that we 
                // can reuse this slot
                m_removedCars.Add(handle.ID);
                m_cars[handle.ID] = new CarData() { Size = -1, Speed = -1 };
            }
        }
        // invalidate the handle so it cannot be used again
        handle.m_id = -1;
    }

    public int GetSize(CarHandle handle)
    {
        // TODO: add error checking!
        return m_cars[handle.ID].Size;
    }
}


class Program
{
    static void Main(string[] args)
    {
        CarManager manager = new CarManager();
        var car1 = manager.CreateCar(10, 20);
        var s1 = manager.GetSize(car1);
        System.Diagnostics.Debug.Assert(s1 == 20);
        var car2 = manager.CreateCar(30, 40);
        var s2 = manager.GetSize(car2);
        System.Diagnostics.Debug.Assert(s2 == 40);

        manager.RemoveCar(ref car1);
        System.Diagnostics.Debug.Assert(car1.ID == -1);
        s2 = manager.GetSize(car2);

        var car3 = manager.CreateCar(50, 60);
        var s3 = manager.GetSize(car3);
        System.Diagnostics.Debug.Assert(s3 == 60);
    }
}
公共结构CarHandle
{
内部int m_id;
内部车把手(内部id)
{
m_id=id;
}
公共int ID{get{return m_ID;}}
}
公共类管理器
{
私有结构卡数据
{
公共交通速度;
公共整数大小;
}
私人列表m_车=新列表();
私有列表m_removedCars=新列表();
公共车把手CreateCar(整数速度,整数大小)
{
var carData=new carData(){Speed=Speed,Size=Size};
//看看是否有空的插槽可以使用
如果(m_removedCars.Count>0)
{
int ix=m_removedCars[m_removedCars.Count-1];
m_removedCars.RemoveAt(m_removedCars.Count-1);
m_cars[ix]=卡数据;
归还新车把(九);
}
其他的
{
m_cars.Add(carData);
归还新车把(m_车。计数-1);
}
}
公共无效删除卡(参考CarHandle handle)
{
如果(m_cars.Count>handle.ID&&m_cars[handle.ID].Size!=-1)
{
//如果是列表中的最后一辆车,则从列表中删除
if(handle.ID==m_cars.Count-1)
{
m_cars.RemoveAt(m_cars.Count-1);
}
其他的
{
//如果我们从列表中删除此项,它将无效
//所有句柄都在这个索引之后,所以我们只需记住
//你能重复使用这个插槽吗
m_removedCars.Add(handle.ID);
m_cars[handle.ID]=new CarData(){Size=-1,Speed=-1};
}
}
//使句柄无效,使其无法再次使用
handle.m_id=-1;
}
public int GetSize(CarHandle句柄)
{
//TODO:添加错误检查!
返回m_车[handle.ID]。大小;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
CarManager manager=新的CarManager();
var car1=manager.CreateCar(10,20);
var s1=manager.GetSize(car1);
System.Diagnostics.Debug.Assert(s1==20);
var car2=manager.CreateCar(30,40);
var s2=manager.GetSize(car2);
System.Diagnostics.Debug.Assert(s2==40);
RemoveCar经理(参考car1);
System.Diagnostics.Debug.Assert(car1.ID==-1);
s2=manager.GetSize(car2);
var car3=manager.CreateCar(50,60);
var s3=manager.GetSize(car3);
System.Diagnostics.Debug.Assert(s3==60);
}
}

感谢您的快速回复!使概念优化不是一个好主意。对类和类型进行清晰易懂的设计。如果将方法放在类之外会使其实例占用更少的空间,除了清晰性之外没有其他缺点,那么C#编译器就可以做到这一点,即使在逻辑上将方法放在类内,因为它不需要保持清晰性。唯一不可能的方法是在运行时将方法附加并重新附加到实例,这是不可能的。(通常——
dynamic
是另一头野兽。)因此,即使从纯理论的角度来看,你也可以预言,在任何合理的世界里,答案都应该是“不”。(尽管世界往往是不合理的。)