Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么可以';I是否同时重写和新建属性(C#)?_C#_.net_Inheritance_Methods - Fatal编程技术网

为什么可以';I是否同时重写和新建属性(C#)?

为什么可以';I是否同时重写和新建属性(C#)?,c#,.net,inheritance,methods,C#,.net,Inheritance,Methods,据我所知,似乎你可以这样做的方法。我想知道的是,当我尝试使用属性时,为什么它不起作用 public class Foo { public virtual object Value { get; set; } } public class Foo<T> : Foo { public override object Value { get { return b

据我所知,似乎你可以这样做的方法。我想知道的是,当我尝试使用属性时,为什么它不起作用

public class Foo
{
    public virtual object Value
    {
        get;
        set;
    }
}

public class Foo<T> : Foo
{
    public override object Value
    {
        get
        {
            return base.Value;
        }
        set
        {
            base.Value = (T)value; //inject type-checking on sets
        }
    }

    public new T Value
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}
公共类Foo
{
公共虚拟对象值
{
收到
设置
}
}
公开课Foo:Foo
{
公共覆盖对象值
{
收到
{
返回基本值;
}
设置
{
base.Value=(T)Value;//对集合进行注入类型检查
}
}
公共新T值
{
获取{return(T)base.Value;}
set{base.Value=Value;}
}
}
来自C#4.0 RC1的错误消息

类型错误1 “ClassLibrary1.Foo”已经存在 包含“值”的定义 ClassLibrary1\Class1.cs 31 22 班级图书馆1


不能有两个使用相同名称的属性。这在C#中是不允许的。唯一的例外是索引器,因为在索引器的情况下,签名会根据索引类型进行更改


不能为只因返回类型不同而不同的方法创建重载。同一规则基本上禁止使用单一名称的属性,因为它在内部是一对没有get访问器参数的方法。

不能有两个使用相同名称的属性。这在C#中是不允许的。唯一的例外是索引器,因为在索引器的情况下,签名会根据索引类型进行更改


不能为只因返回类型不同而不同的方法创建重载。同一规则基本上禁止使用单一名称的属性,因为它在内部是一对没有get访问器参数的方法。

同一属性有两个定义
一个由override定义。。。一个接一个。返回类型不是方法签名中的区别特征,即,如果签名仅在返回类型中不同,则认为签名相同。因此,请使用覆盖或新建

在您的情况下,您可以使用new而不是override来实现目标。但是,在使用新的时,必须始终考虑执行精益取决于调用该方法的类型。即

var foo = new Foo();
var foo_ = new Foo<string>();

foo.Value            // calls the implementation on Foo 
foo_.Value           // calls the implementation on Foo<T>
((Foo) foo).Value    // calls the implementation on Foo
var foo=new foo();
var foo_=新foo();
Value//调用foo上的实现
Value//调用foo上的实现
((Foo)Foo).Value//调用Foo上的实现

您有两个相同属性的定义
一个由覆盖定义。。。一个接一个。返回类型不是方法签名中的区别特征,即,如果签名仅在返回类型中不同,则认为签名相同。因此,请使用覆盖或新建

在您的情况下,您可以使用new而不是override来实现目标。但是,在使用新的时,必须始终考虑执行精益取决于调用该方法的类型。即

var foo = new Foo();
var foo_ = new Foo<string>();

foo.Value            // calls the implementation on Foo 
foo_.Value           // calls the implementation on Foo<T>
((Foo) foo).Value    // calls the implementation on Foo
var foo=new foo();
var foo_=新foo();
Value//调用foo上的实现
Value//调用foo上的实现
((Foo)Foo).Value//调用Foo上的实现

如果您执行以下操作,则可以执行此操作

public interface IFoo<T>
{
    T Value { get; set; }
}

public class Foo<T> : Foo, IFoo<T>
{
    T IFoo.Value
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}
公共接口IFoo
{
T值{get;set;}
}
公共类Foo:Foo,IFoo
{
T IFoo.值
{
获取{return(T)base.Value;}
set{base.Value=Value;}
}
}
唯一的一点是,当您引用时,您必须使用接口类型。。。i、 e

   IFoo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give you the typed version

   Foo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give throw an exception
IFoo myfoo=new Foo();
int result=myFoo.Value//这将为您提供键入的版本
Foo myfoo=新Foo();
int result=myFoo.Value//这将导致抛出一个异常

如果您执行以下操作,则可以执行此操作

public interface IFoo<T>
{
    T Value { get; set; }
}

public class Foo<T> : Foo, IFoo<T>
{
    T IFoo.Value
    {
        get { return (T)base.Value; }
        set { base.Value = value; }
    }
}
公共接口IFoo
{
T值{get;set;}
}
公共类Foo:Foo,IFoo
{
T IFoo.值
{
获取{return(T)base.Value;}
set{base.Value=Value;}
}
}
唯一的一点是,当您引用时,您必须使用接口类型。。。i、 e

   IFoo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give you the typed version

   Foo<int> myfoo = new Foo<int>();
   int result = myFoo.Value;    //This will give throw an exception
IFoo myfoo=new Foo();
int result=myFoo.Value//这将为您提供键入的版本
Foo myfoo=新Foo();
int result=myFoo.Value//这将导致抛出一个异常

你可以通过一段对话来了解这一点

public interface IFoo
{
    object Value { get; set; }
}

public class Foo<T> : IFoo
{
    object _value = null;
    object IFoo.Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public T Value
    {
        get;
        set;
    }
}
公共接口IFoo
{
对象值{get;set;}
}
公共类Foo:IFoo
{
对象_值=null;
对象IFoo.Value
{
获取{返回_值;}
设置{u value=value;}
}
公共价值
{
收到
设置
}
}

你可以通过一段对话来了解这一点

public interface IFoo
{
    object Value { get; set; }
}

public class Foo<T> : IFoo
{
    object _value = null;
    object IFoo.Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public T Value
    {
        get;
        set;
    }
}
公共接口IFoo
{
对象值{get;set;}
}
公共类Foo:IFoo
{
对象_值=null;
对象IFoo.Value
{
获取{返回_值;}
设置{u value=value;}
}
公共价值
{
收到
设置
}
}

潜在的问题是永远无法知道要使用哪个属性

比如说,

Foo<int> s = new Foo<int>();

s.Value = "hmmm";
foos=newfoo();
s、 Value=“hmmm”;

那么应该使用哪种属性呢?int派生自对象,也满足通用属性版本的约束

根本的问题是永远无法知道使用哪个属性

比如说,

Foo<int> s = new Foo<int>();

s.Value = "hmmm";
foos=newfoo();
s、 Value=“hmmm”;

那么应该使用哪种属性呢?int派生自对象,也满足通用属性版本的约束

C++/CLI可以做到这一点,即使C#不能做到。在C++/CLI中,您可以显式地说覆盖了哪个方法,因此名称不必匹配。

C++/CLI可以做到这一点,即使C#不能做到。在C++/CLI中,您可以显式地说覆盖了哪个方法,因此名称不必匹配。

我必须想出一个稍微不同的解决方法,事实上,因为我的基类不是抽象的,它实际上应该可以使用