简体   繁体   English

C#中的通用方法访问隐藏属性

[英]generic method access hidden property in c#

I'm currently having trouble and I have no clue how to fix it. 我目前遇到麻烦,不知道如何解决。

I have 2 classes: 我有2节课:

class A 
{
 public string MyParam { get; set; }
}

class B : A
{
  public new string MyParam { get { return base.MyParam != null ? base.MyParam.Substring(1) : null; } }
}

When I try to access the B.MyParam it works when I have a the correct type, but in most of my methods I have a generic type with : 当我尝试访问B.MyParam时,只要我拥有正确的类型,它就可以工作,但是在我的大多数方法中,我都有一个具有以下类型的泛型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        public class A
        {
            public string MyParam { get; set; }
        }

        public class B : A
        {
            public new string MyParam
            {
                get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
            }
        }
        public static void MyMethod<T>(T variable) where T : A
        {
            Console.WriteLine(variable.MyParam);//this print hello
            Console.WriteLine((variable as B).MyParam);//this print ello (exactly what i want)
            Console.WriteLine(typeof(T)); // this print ConsoleApplication1.Program+A
            Console.WriteLine(variable.GetType()); // this print ConsoleApplication1.Program+B

            // so i need something like that

            Console.WriteLine((variable as variable.GetType()).MyParam); // this line is invalid
        }

        static void Main(string[] args)
        {
            A a = new B();
            a.MyParam = "Hello";
            Console.WriteLine(a.GetType());
            MyMethod(a); 
            Console.ReadKey();
        }
    }
}

Is there a way to do it? 有办法吗? Thank you in advance. 先感谢您。

EDIT: it seems that what i want is : 编辑:似乎我想要的是:

 dynamic variable2 = Convert.ChangeType(variable, variable.GetType());
 Console.WriteLine(variable2.MyParam); 

Your code doesn´t make any sense. 您的代码没有任何意义。 If A inherits from B you´ll need A to override the base-implementation for your property. 如果A继承自B则需要A 覆盖属性的基本实现。 So I´ll assume you should rethink your inheritance-chain. 因此,我假设您应该重新考虑您的继承链。

You can use override for this. 您可以为此使用override Thus when your variable -parameter is of your base-class (I renamed that to A ) you´re calling the base-method, if it´sa derived instance (here B ) you´re calling the override: 因此,当您的variable -parameter是您的基类(我将其重命名为A )时,您在调用基本方法,如果它是派生实例(在这里B ),则您在调用覆盖:

class A
{
    public virtual string MyParam { get; }
}

class B : A // note here that B derives from A, not the other way round
{
    public override string MyParam 
    { 
        get { return base.MyParam != null ? base.MyParam.Substring(1) : null; },
        set { ... }
    }
}

EDIT: While new intrduces a new member which (accidentally) has the same name (and signature) as the base-member it effectivly hides the base-member. 编辑:虽然new引入了一个新成员(偶然地)具有与基本成员相同的名称(和签名),但它有效地隐藏了基本成员。 Thus you effectivly have two members. 因此,您实际上有两个成员。 Your only way to indicate which member should be used is by casting your instance to the desired class from which you need the implementation. 指示应使用哪个成员的唯一方法是将实例强制转换为需要实现的所需类。 However this somehow breaks the purpose of generics as the generic member has to know the exact types that are possible for the type-parameter. 但是,这在某种程度上打破了泛型的目的,因为泛型成员必须知道类型参数可能的确切类型。

Anyway this seems like broken design to me, as you´re actually creating a new member which has another meaning . 无论如何,这对我来说似乎是破损的设计,因为您实际上正在创建一个具有其他含义的新成员。 So you should also give it a new name . 因此,您也应该给它起一个新的名字

Based on your generic method, I think all you need is an interface. 根据您的通用方法,我认为您只需要一个接口即可。

public interface IMyParam
{
    string MyParam { get; set; }
}

Your classes. 您的课程。

class A : IMyParam
{
    public virtual string MyParam { get; set; }
}

class B : A
{
    public override string MyParam
    {
        get { return base.MyParam != null ? base.MyParam.Substring(1) : null; }
    }
}

And your method, won't need to be generic. 而且您的方法不需要通用。

public void MyMethod(IMyParam variable)
{
    // Your logic here, for example.
    Console.WriteLine(variable.MyParam);
}

Calling your method. 调用您的方法。

A a = new A();
a.MyParam = "Hello";

B b = new B();
b.MyParam = "Hello";

A ab = new B();
ab.MyParam = "Hello";

MyMethod(a); // Prints Hello
MyMethod(b); // Prints ello
MyMethod(ab); // Prints ello

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM